^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Realtek Bluetooth USB download firmware driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * the Free Software Foundation; either version 2 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/dcache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/cdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/version.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <net/bluetooth/bluetooth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <net/bluetooth/hci_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <net/bluetooth/hci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include "rtk_misc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define BDADDR_STRING_LEN 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define BDADDR_FILE "/opt/bdaddr"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct cfg_list_item {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u8 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u8 data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static struct list_head list_configs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define EXTRA_CONFIG_FILE "/opt/rtk_btconfig.txt"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static struct list_head list_extracfgs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define CMD_CMP_EVT 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define PKT_LEN 300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define MSG_TO 1000 //us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define PATCH_SEG_MAX 252
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define DATA_END 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define DOWNLOAD_OPCODE 0xfc20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* This command is used only for TV patch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * if host is going to suspend state, it should send this command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Controller. Controller will scan the special advertising packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * which indicates Controller to wake up host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define STARTSCAN_OPCODE 0xfc28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define TRUE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define FALSE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define CMD_HDR_LEN sizeof(struct hci_command_hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define EVT_HDR_LEN sizeof(struct hci_event_hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define CMD_CMP_LEN sizeof(struct hci_ev_cmd_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define HCI_CMD_READ_BD_ADDR 0x1009
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define HCI_VENDOR_CHANGE_BDRATE 0xfc17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define HCI_VENDOR_READ_RTK_ROM_VERISION 0xfc6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define HCI_VENDOR_READ_LMP_VERISION 0x1001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define ROM_LMP_NONE 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define ROM_LMP_8723a 0x1200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define ROM_LMP_8723b 0x8723
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define ROM_LMP_8821a 0X8821
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define ROM_LMP_8761a 0X8761
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define ROM_LMP_8822b 0X8822
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define ROM_LMP_8852a 0x8852
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct rtk_eversion_evt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) uint8_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) uint8_t version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) } __attribute__ ((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct rtk_epatch_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) uint16_t chipID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) uint16_t patch_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) uint32_t start_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) } __attribute__ ((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct rtk_epatch {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) uint8_t signature[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) uint32_t fw_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) uint16_t number_of_total_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct rtk_epatch_entry entry[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) } __attribute__ ((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct rtk_extension_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) uint8_t opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) uint8_t length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) uint8_t *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) } __attribute__ ((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) //signature: Realtech
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) const uint8_t RTK_EPATCH_SIGNATURE[8] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) { 0x52, 0x65, 0x61, 0x6C, 0x74, 0x65, 0x63, 0x68 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) //Extension Section IGNATURE:0x77FD0451
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) const uint8_t Extension_Section_SIGNATURE[4] = { 0x51, 0x04, 0xFD, 0x77 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) uint16_t project_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ROM_LMP_8723a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ROM_LMP_8723b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ROM_LMP_8821a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ROM_LMP_8761a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ROM_LMP_8822b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ROM_LMP_8723b, /* RTL8723DU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ROM_LMP_8821a, /* RTL8821CU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ROM_LMP_8822b, /* RTL8822CU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ROM_LMP_8761a, /* index 14 for 8761BU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ROM_LMP_8852a, /* index 18 for 8852AU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ROM_LMP_8723b, /* index 19 for 8723FU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ROM_LMP_8852a, /* index 20 for 8852BU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ROM_LMP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ROM_LMP_8852a, /* index 25 for 8852CU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) enum rtk_endpoit {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) CTRL_EP = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) INTR_EP = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) BULK_EP = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ISOC_EP = 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* software id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define RTLPREVIOUS 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define RTL8822BU 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define RTL8723DU 0x71
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define RTL8821CU 0x72
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define RTL8822CU 0x73
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define RTL8761BU 0x74
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define RTL8852AU 0x75
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define RTL8723FU 0x76
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define RTL8852BU 0x77
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define RTL8852CU 0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) uint16_t prod_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) uint16_t lmp_sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) char * mp_patch_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) char * patch_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) char * config_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u8 chip_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) } patch_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct list_head list_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct usb_interface *intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) patch_info *patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) } dev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) dev_data *dev_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int pipe_in, pipe_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) uint8_t *send_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) uint8_t *rcv_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct hci_command_hdr *cmd_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct hci_event_hdr *evt_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct hci_ev_cmd_complete *cmd_cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) uint8_t *req_para, *rsp_para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) uint8_t *fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int pkt_len, fw_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) } xchange_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) uint8_t index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) uint8_t data[PATCH_SEG_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) } __attribute__ ((packed)) download_cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) uint8_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) uint8_t index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) } __attribute__ ((packed)) download_rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define RTK_VENDOR_CONFIG_MAGIC 0x8723ab55
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) const u8 cfg_magic[4] = { 0x55, 0xab, 0x23, 0x87 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct rtk_bt_vendor_config_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) uint16_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) uint8_t entry_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) uint8_t entry_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) } __attribute__ ((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct rtk_bt_vendor_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) uint32_t signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) uint16_t data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct rtk_bt_vendor_config_entry entry[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) } __attribute__ ((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define BT_CONFIG_HDRLEN sizeof(struct rtk_bt_vendor_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static uint8_t gEVersion = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static dev_data *dev_data_find(struct usb_interface *intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static patch_info *get_patch_entry(struct usb_device *udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static int load_firmware(dev_data * dev_entry, uint8_t ** buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static void init_xdata(xchange_data * xdata, dev_data * dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int check_fw_version(xchange_data * xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int download_data(xchange_data * xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int send_hci_cmd(xchange_data * xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static int rcv_hci_evt(xchange_data * xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static uint8_t rtk_get_eversion(dev_data * dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static patch_info fw_patch_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* { pid, lmp_sub, mp_fw_name, fw_name, config_name, chip_type } */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {0x1724, 0x1200, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", RTLPREVIOUS}, /* RTL8723A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {0x8723, 0x1200, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", RTLPREVIOUS}, /* 8723AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {0xA723, 0x1200, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", RTLPREVIOUS}, /* 8723AE for LI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {0x0723, 0x1200, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", RTLPREVIOUS}, /* 8723AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {0x3394, 0x1200, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", RTLPREVIOUS}, /* 8723AE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {0x0724, 0x1200, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", RTLPREVIOUS}, /* 8723AU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {0x8725, 0x1200, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", RTLPREVIOUS}, /* 8723AU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {0x872A, 0x1200, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", RTLPREVIOUS}, /* 8723AU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {0x872B, 0x1200, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", RTLPREVIOUS}, /* 8723AU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {0xb720, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {0xb72A, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {0xb728, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE for LC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {0xb723, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {0xb72B, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {0xb001, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE for HP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {0xb002, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {0xb003, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {0xb004, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {0xb005, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {0x3410, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {0x3416, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {0x3459, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {0xE085, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE for Foxconn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {0xE08B, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE for Foxconn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {0xE09E, 0x8723, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", RTLPREVIOUS}, /* RTL8723BE for Foxconn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {0xA761, 0x8761, "mp_rtl8761a_fw", "rtl8761au_fw", "rtl8761a_config", RTLPREVIOUS}, /* RTL8761AU only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {0x818B, 0x8761, "mp_rtl8761a_fw", "rtl8761aw_fw", "rtl8761aw_config", RTLPREVIOUS}, /* RTL8761AW + 8192EU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {0x818C, 0x8761, "mp_rtl8761a_fw", "rtl8761aw_fw", "rtl8761aw_config", RTLPREVIOUS}, /* RTL8761AW + 8192EU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {0x8760, 0x8761, "mp_rtl8761a_fw", "rtl8761au8192ee_fw", "rtl8761a_config", RTLPREVIOUS}, /* RTL8761AU + 8192EE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {0xB761, 0x8761, "mp_rtl8761a_fw", "rtl8761au_fw", "rtl8761a_config", RTLPREVIOUS}, /* RTL8761AUV only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {0x8761, 0x8761, "mp_rtl8761a_fw", "rtl8761au8192ee_fw", "rtl8761a_config", RTLPREVIOUS}, /* RTL8761AU + 8192EE for LI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {0x8A60, 0x8761, "mp_rtl8761a_fw", "rtl8761au8812ae_fw", "rtl8761a_config", RTLPREVIOUS}, /* RTL8761AU + 8812AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {0x3527, 0x8761, "mp_rtl8761a_fw", "rtl8761au8192ee_fw", "rtl8761a_config", RTLPREVIOUS}, /* RTL8761AU + 8814AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {0x8821, 0x8821, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", RTLPREVIOUS}, /* RTL8821AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {0x0821, 0x8821, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", RTLPREVIOUS}, /* RTL8821AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {0x0823, 0x8821, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", RTLPREVIOUS}, /* RTL8821AU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {0x3414, 0x8821, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", RTLPREVIOUS}, /* RTL8821AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {0x3458, 0x8821, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", RTLPREVIOUS}, /* RTL8821AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {0x3461, 0x8821, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", RTLPREVIOUS}, /* RTL8821AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {0x3462, 0x8821, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", RTLPREVIOUS}, /* RTL8821AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {0xb82c, 0x8822, "mp_rtl8822bu_fw", "rtl8822bu_fw", "rtl8822bu_config", RTL8822BU}, /* RTL8822BU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {0xd720, 0x8723, "mp_rtl8723du_fw", "rtl8723du_fw", "rtl8723du_config", RTL8723DU}, /* RTL8723DU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {0xd723, 0x8723, "mp_rtl8723du_fw", "rtl8723du_fw", "rtl8723du_config", RTL8723DU}, /* RTL8723DU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {0xd739, 0x8723, "mp_rtl8723du_fw", "rtl8723du_fw", "rtl8723du_config", RTL8723DU}, /* RTL8723DU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {0xb009, 0x8723, "mp_rtl8723du_fw", "rtl8723du_fw", "rtl8723du_config", RTL8723DU}, /* RTL8723DU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {0x0231, 0x8723, "mp_rtl8723du_fw", "rtl8723du_fw", "rtl8723du_config", RTL8723DU}, /* RTL8723DU for LiteOn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {0xb820, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {0xc820, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {0xc821, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {0xc823, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {0xc824, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {0xc825, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {0xc827, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {0xc025, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {0xc024, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {0xc030, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {0xb00a, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {0xb00e, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {0xc032, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {0x4000, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for LiteOn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {0x4001, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for LiteOn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {0x3529, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {0x3530, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {0x3532, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {0x3533, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {0x3538, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {0x3539, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {0x3558, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {0x3559, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {0x3581, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {0x3540, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {0x3541, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for GSD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {0x3543, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE for GSD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {0xc80c, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CUH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {0xc82c, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {0xc82e, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {0xc81d, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {0xd820, 0x8822, "mp_rtl8821du_fw", "rtl8821du_fw", "rtl8821du_config", RTL8822CU}, /* RTL8821DU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {0xc822, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {0xc82b, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {0xb00c, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {0xb00d, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {0xc123, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {0xc126, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {0xc127, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {0xc128, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {0xc129, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {0xc131, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {0xc136, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {0x3549, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {0x3548, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE for Azurewave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {0xc125, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {0x4005, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE for LiteOn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {0x3051, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE for LiteOn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {0x18ef, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {0x161f, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {0x3053, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {0xc547, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {0x3553, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {0x3555, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {0xc82f, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE-VS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {0xc02f, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE-VS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {0xc03f, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE-VS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {0x8771, 0x8761, "mp_rtl8761b_fw", "rtl8761bu_fw", "rtl8761bu_config", RTL8761BU}, /* RTL8761BU only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {0xa725, 0x8761, "mp_rtl8761b_fw", "rtl8725au_fw", "rtl8725au_config", RTL8761BU}, /* RTL8725AU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {0xa72A, 0x8761, "mp_rtl8761b_fw", "rtl8725au_fw", "rtl8725au_config", RTL8761BU}, /* RTL8725AU BT only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {0x885a, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {0x8852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {0xa852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {0x2852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {0x385a, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {0x3852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {0x1852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {0x4852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {0x4006, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {0x3561, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {0x3562, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {0x588a, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {0x589a, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {0x590a, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {0xc125, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {0xe852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) //{0xb852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {0xc852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {0xc549, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {0xc127, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {0x3565, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {0xb733, 0x8723, "mp_rtl8723fu_fw", "rtl8723fu_fw", "rtl8723fu_config", RTL8723FU}, /* RTL8723FU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {0xb73a, 0x8723, "mp_rtl8723fu_fw", "rtl8723fu_fw", "rtl8723fu_config", RTL8723FU}, /* RTL8723FU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {0xf72b, 0x8723, "mp_rtl8723fu_fw", "rtl8723fu_fw", "rtl8723fu_config", RTL8723FU}, /* RTL8723FU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {0x8851, 0x8852, "mp_rtl8851au_fw", "rtl8851au_fw", "rtl8851au_config", RTL8852BU}, /* RTL8851AU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {0xa85b, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {0xb852, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {0xb85b, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {0xb85c, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {0x3571, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {0x3570, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {0x3572, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {0x4b06, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {0x885b, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {0x886b, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {0x887b, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {0xc559, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {0xb052, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {0xb152, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {0xb252, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {0x4853, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {0x1670, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {0xc85a, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {0x0852, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {0x5852, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {0xc85c, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {0x885c, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {0x886c, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {0x887c, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {0x4007, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* NOTE: must append patch entries above the null entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {0, 0, NULL, NULL, NULL, 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static LIST_HEAD(dev_data_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) void util_hexdump(const u8 *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static const char hexdigits[] = "0123456789abcdef";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) char str[16 * 3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!buf || !len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) str[((i % 16) * 3)] = hexdigits[buf[i] >> 4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) str[((i % 16) * 3) + 1] = hexdigits[buf[i] & 0xf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) str[((i % 16) * 3) + 2] = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if ((i + 1) % 16 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) str[16 * 3 - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) RTKBT_DBG("%s", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (i % 16 > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) str[(i % 16) * 3 - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) RTKBT_DBG("%s", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) #if defined RTKBT_SWITCH_PATCH || defined RTKBT_TV_POWERON_WHITELIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) int __rtk_send_hci_cmd(struct usb_device *udev, u8 *buf, u16 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) unsigned int pipe = usb_sndctrlpipe(udev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) result = usb_control_msg(udev, pipe, 0, USB_TYPE_CLASS, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) buf, size, 1000); /* 1000 msecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) RTKBT_ERR("%s: Couldn't send hci cmd, err %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) int __rtk_recv_hci_evt(struct usb_device *udev, u8 *buf, u8 len, u16 opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) int recv_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) unsigned int pipe = usb_rcvintpipe(udev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct hci_event_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct hci_ev_cmd_complete *cmd_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (len < sizeof(*hdr) + sizeof(*cmd_cmpl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) RTKBT_ERR("%s: Invalid buf length %u", __func__, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) for (i = 0; i < 5; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) result = usb_interrupt_msg(udev, pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) (void *)buf, PKT_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) &recv_length, MSG_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (result >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) RTKBT_ERR("%s; Couldn't receive HCI event, err %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return result;
^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) /* Ignore the event which is not command complete event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (recv_length < sizeof(*hdr) + sizeof(*cmd_cmpl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) hdr = (struct hci_event_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) cmd_cmpl = (struct hci_ev_cmd_complete *)(buf + sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (hdr->evt == 0x0e) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (opcode == cmd_cmpl->opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return recv_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static inline struct inode *file_inode(const struct file *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return f->f_path.dentry->d_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static int config_lists_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) INIT_LIST_HEAD(&list_configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) INIT_LIST_HEAD(&list_extracfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static void config_lists_free(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct list_head *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct list_head *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct list_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct cfg_list_item *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (!list_empty(&list_extracfgs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) list_splice_tail(&list_extracfgs, &list_configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) head = &list_configs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) list_for_each_safe(iter, tmp, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) n = list_entry(iter, struct cfg_list_item, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) list_del(&n->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) kfree(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) INIT_LIST_HEAD(&list_configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) INIT_LIST_HEAD(&list_extracfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static void line_process(char *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) char *argv[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int argc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) u8 l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) u8 i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) char *ptr = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) char *head = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct cfg_list_item *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) while ((ptr = strsep(&head, ", \t")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (!ptr[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) argv[argc++] = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (argc >= 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) RTKBT_WARN("%s: Config item is too long", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (argc < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) RTKBT_WARN("%s: Invalid Config item, ignore", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) offset = simple_strtoul(argv[0], NULL, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) offset = offset | (simple_strtoul(argv[1], NULL, 16) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) l = (u8)simple_strtoul(argv[2], NULL, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (l != (u8)(argc - 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) RTKBT_ERR("invalid len %u", l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return;
^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) item = kzalloc(sizeof(*item) + l, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (!item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) RTKBT_WARN("%s: Cannot alloc mem for item, %04lx, %u", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) offset, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) item->offset = (u16)offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) item->len = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) for (i = 0; i < l; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) item->data[i] = (u8)simple_strtoul(argv[3 + i], NULL, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) list_add_tail(&item->list, &list_extracfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static void config_process(u8 *buff, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) char *head = (void *)buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) char *ptr = (void *)buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) while ((ptr = strsep(&head, "\n\r")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (!ptr[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) line_process(ptr, strlen(ptr) + 1);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static void config_file_proc(const char *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) u8 tbuf[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) loff_t pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) file = filp_open(path, O_RDONLY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (IS_ERR(file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (!S_ISREG(file_inode(file)->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) size = i_size_read(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (size <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) memset(tbuf, 0, sizeof(tbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) rc = kernel_read(file, tbuf, size, &pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) rc = kernel_read(file, 0, tbuf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) fput(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (rc != size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (rc >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) tbuf[rc++] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) tbuf[rc++] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) config_process(tbuf, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) int patch_add(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) dev_data *dev_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) RTKBT_DBG("patch_add");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) dev_entry = dev_data_find(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (NULL != dev_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) udev = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) #ifdef BTUSB_RPM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) RTKBT_DBG("auto suspend is enabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) usb_enable_autosuspend(udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) pm_runtime_set_autosuspend_delay(&(udev->dev), 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) RTKBT_DBG("auto suspend is disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) usb_disable_autosuspend(udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) dev_entry = kzalloc(sizeof(dev_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dev_entry->intf = intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) dev_entry->udev = udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) dev_entry->patch_entry = get_patch_entry(udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (NULL == dev_entry->patch_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) kfree(dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) list_add(&dev_entry->list_node, &dev_data_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) /* Should reset the gEVersion to 0xff, otherwise the stored gEVersion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * would cause rtk_get_eversion() returning previous gEVersion if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * change to different ECO chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * This would cause downloading wrong patch, and the controller can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * work. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) RTKBT_DBG("%s: Reset gEVersion to 0xff", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) gEVersion = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) void patch_remove(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) dev_data *dev_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) udev = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) #ifdef BTUSB_RPM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) usb_disable_autosuspend(udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) dev_entry = dev_data_find(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (NULL == dev_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) RTKBT_DBG("patch_remove");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) list_del(&dev_entry->list_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) kfree(dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static int send_reset_command(xchange_data *xdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) RTKBT_DBG("HCI reset.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) xdata->cmd_hdr->opcode = cpu_to_le16(HCI_OP_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) xdata->cmd_hdr->plen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) xdata->pkt_len = CMD_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) ret_val = send_hci_cmd(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) RTKBT_ERR("failed to send hci cmd.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ret_val = rcv_hci_evt(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) RTKBT_ERR("failed to recv hci event.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static inline int get_max_patch_size(u8 chip_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int max_patch_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) switch (chip_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) case RTLPREVIOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) max_patch_size = 24 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) case RTL8822BU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) max_patch_size = 25 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) case RTL8723DU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) case RTL8822CU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case RTL8761BU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) case RTL8821CU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) max_patch_size = 40 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) case RTL8852AU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) max_patch_size = 0x114D0 + 529; /* 69.2KB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) case RTL8723FU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) max_patch_size = 0xC4Cf + 529; /* 49.2KB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) case RTL8852BU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) max_patch_size = 0x104D0 + 529; /* 65KB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) case RTL8852CU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) max_patch_size = 0x130D0 + 529; /* 76.2KB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) max_patch_size = 40 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return max_patch_size;
^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) int download_patch(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dev_data *dev_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) patch_info *pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) xchange_data *xdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) uint8_t *fw_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) int max_patch_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) RTKBT_DBG("download_patch start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) dev_entry = dev_data_find(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (NULL == dev_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) ret_val = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) RTKBT_ERR("NULL == dev_entry");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) goto patch_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) xdata = kzalloc(sizeof(xchange_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (NULL == xdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) ret_val = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) RTKBT_DBG("NULL == xdata");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) goto patch_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) init_xdata(xdata, dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ret_val = check_fw_version(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) RTKBT_ERR("Failed to get Local Version Information");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) goto patch_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) } else if (ret_val > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) RTKBT_DBG("Firmware already exists");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /* Patch alread exists, just return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (gEVersion == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) RTKBT_DBG("global_version is not set, get it!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) gEVersion = rtk_get_eversion(dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) goto patch_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) xdata->fw_len = load_firmware(dev_entry, &xdata->fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (xdata->fw_len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) RTKBT_ERR("load firmware failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ret_val = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) goto patch_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) fw_buf = xdata->fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) pinfo = dev_entry->patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (!pinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) RTKBT_ERR("%s: No patch entry", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) ret_val = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) goto patch_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) max_patch_size = get_max_patch_size(pinfo->chip_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (xdata->fw_len > max_patch_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) RTKBT_ERR("FW/CONFIG total length larger than allowed %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) max_patch_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ret_val = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) goto patch_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) ret_val = download_data(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) RTKBT_ERR("download_data failed, err %d", ret_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) goto patch_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) ret_val = check_fw_version(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (ret_val <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) RTKBT_ERR("%s: Read Local Version Info failure after download",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ret_val = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) goto patch_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) patch_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) kfree(fw_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) patch_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (xdata != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (xdata->send_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) kfree(xdata->send_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (xdata->rcv_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) kfree(xdata->rcv_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) kfree(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) RTKBT_DBG("Rtk patch end %d", ret_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) #ifdef RTKBT_SWITCH_PATCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /* @return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * -1: error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) * 0: download patch successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * >0: patch already exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) int download_lps_patch(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) dev_data *dev_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) xchange_data *xdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) uint8_t *fw_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) char name1[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) char *origin_name1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) char name2[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) char *origin_name2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) RTKBT_DBG("Download LPS Patch start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) dev_entry = dev_data_find(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (!dev_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) RTKBT_ERR("No Patch found");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) xdata = kzalloc(sizeof(xchange_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (!xdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) RTKBT_ERR("Couldn't alloc xdata");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) init_xdata(xdata, dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) result = check_fw_version(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) RTKBT_ERR("Failed to get Local Version Information");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) goto patch_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) } else if (result > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) RTKBT_DBG("Firmware already exists");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* Patch alread exists, just return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (gEVersion == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) RTKBT_DBG("global_version is not set, get it!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) gEVersion = rtk_get_eversion(dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) goto patch_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) origin_name1 = dev_entry->patch_entry->patch_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) origin_name2 = dev_entry->patch_entry->config_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) snprintf(name1, sizeof(name1), "lps_%s", origin_name1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) snprintf(name2, sizeof(name2), "lps_%s", origin_name2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) dev_entry->patch_entry->patch_name = name1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) dev_entry->patch_entry->config_name = name2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) RTKBT_INFO("Loading %s and %s", name1, name2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) xdata->fw_len = load_firmware(dev_entry, &xdata->fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) dev_entry->patch_entry->patch_name = origin_name1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) dev_entry->patch_entry->config_name = origin_name2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (xdata->fw_len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) RTKBT_ERR("load firmware failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) goto patch_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) fw_buf = xdata->fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) pinfo = dev_entry->patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (!pinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) RTKBT_ERR("%s: No patch entry", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) goto patch_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) max_patch_size = get_max_patch_size(pinfo->chip_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (xdata->fw_len > max_patch_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) RTKBT_ERR("FW/CONFIG total length larger than allowed %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) max_patch_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) goto patch_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) result = download_data(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) RTKBT_ERR("download_data failed, err %d", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) goto patch_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) result = check_fw_version(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (result <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) RTKBT_ERR("%s: Read Local Version Info failure after download",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) goto patch_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) patch_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) kfree(fw_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) patch_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (xdata->send_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) kfree(xdata->send_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (xdata->rcv_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) kfree(xdata->rcv_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) kfree(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) RTKBT_DBG("Download LPS Patch end %d", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) int set_scan(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) dev_data *dev_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) xchange_data *xdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) RTKBT_DBG("%s", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) dev_entry = dev_data_find(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (!dev_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) xdata = kzalloc(sizeof(xchange_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (!xdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) RTKBT_ERR("Could not alloc xdata");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) init_xdata(xdata, dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if ( !xdata->send_pkt || !xdata->rcv_pkt ){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) xdata->cmd_hdr->opcode = cpu_to_le16(STARTSCAN_OPCODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) xdata->cmd_hdr->plen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) xdata->pkt_len = CMD_HDR_LEN + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) xdata->send_pkt[CMD_HDR_LEN] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) result = send_hci_cmd(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) result = rcv_hci_evt(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) kfree(xdata->send_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) kfree(xdata->rcv_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) kfree(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) RTKBT_DBG("%s done", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) dev_data *dev_data_find(struct usb_interface * intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) dev_data *dev_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) list_for_each_entry(dev_entry, &dev_data_list, list_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (dev_entry->intf == intf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) patch_info *patch = dev_entry->patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (!patch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) RTKBT_INFO("chip type value: 0x%02x", patch->chip_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return dev_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) patch_info *get_patch_entry(struct usb_device * udev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) patch_info *patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) uint16_t pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) patch_entry = fw_patch_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) pid = le16_to_cpu(udev->descriptor.idProduct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) RTKBT_DBG("pid = 0x%x", pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) while (pid != patch_entry->prod_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (0 == patch_entry->prod_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) RTKBT_DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) ("get_patch_entry =NULL, can not find device pid in patch_table");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return NULL; //break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) patch_entry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static int is_mac(u8 chip_type, u16 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) switch (chip_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) case RTL8822BU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) case RTL8723DU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) case RTL8821CU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (offset == 0x0044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) case RTL8822CU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) case RTL8761BU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) case RTL8852AU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) case RTL8723FU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) case RTL8852BU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) case RTL8852CU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (offset == 0x0030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) case RTLPREVIOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (offset == 0x003c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static uint16_t get_mac_offset(u8 chip_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) switch (chip_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) case RTL8822BU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) case RTL8723DU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) case RTL8821CU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return 0x0044;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) case RTL8822CU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) case RTL8761BU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) case RTL8852AU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) case RTL8723FU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) case RTL8852BU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) case RTL8852CU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return 0x0030;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) case RTLPREVIOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return 0x003c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return 0x003c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static void merge_configs(struct list_head *head, struct list_head *head2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct list_head *epos, *enext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) struct list_head *pos, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) struct cfg_list_item *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) struct cfg_list_item *extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (!head || !head2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (list_empty(head2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (list_empty(head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) list_splice_tail(head2, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) INIT_LIST_HEAD(head2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /* Add or update & replace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) list_for_each_safe(epos, enext, head2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) extra = list_entry(epos, struct cfg_list_item, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) list_for_each_safe(pos, next, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) n = list_entry(pos, struct cfg_list_item, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (extra->offset == n->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (extra->len < n->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) /* Update the cfg data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) RTKBT_INFO("Update cfg: ofs %04x len %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) n->offset, n->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) memcpy(n->data, extra->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) extra->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) list_del(epos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) kfree(extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* Replace the item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) list_del(epos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) list_replace_init(pos, epos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) /* free the old item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) kfree(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (list_empty(head2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) list_for_each_safe(epos, enext, head2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) extra = list_entry(epos, struct cfg_list_item, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) RTKBT_INFO("Add new cfg: ofs %04x, len %u", extra->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) extra->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) /* Add the item to list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) list_del(epos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) list_add_tail(epos, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) int rtk_parse_config_file(u8 *config_buf, int filelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) struct rtk_bt_vendor_config *config = (void *)config_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) u16 config_len = 0, temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) struct rtk_bt_vendor_config_entry *entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) u32 i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct cfg_list_item *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (!config_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) config_len = le16_to_cpu(config->data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) entry = config->entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if (le32_to_cpu(config->signature) != RTK_VENDOR_CONFIG_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) RTKBT_ERR("sig magic num %08x, not rtk vendor magic %08x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) config->signature, RTK_VENDOR_CONFIG_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (config_len != filelen - BT_CONFIG_HDRLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) RTKBT_ERR("config length %u is not right %u", config_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) (u16)(filelen - BT_CONFIG_HDRLEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) for (i = 0; i < config_len;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /* Add config item to list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) item = kzalloc(sizeof(*item) + entry->entry_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) item->offset = le16_to_cpu(entry->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) item->len = entry->entry_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) memcpy(item->data, entry->entry_data, item->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) list_add_tail(&item->list, &list_configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) RTKBT_ERR("Cannot alloc mem for entry %04x, %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) entry->offset, entry->entry_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) temp = entry->entry_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) sizeof(struct rtk_bt_vendor_config_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) i += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) entry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) (struct rtk_bt_vendor_config_entry *)((uint8_t *) entry +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return 0;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) uint8_t rtk_get_fw_project_id(uint8_t * p_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) uint8_t opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) uint8_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) uint8_t data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) opcode = *p_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) len = *(p_buf - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (opcode == 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (len == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) data = *(p_buf - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) RTKBT_DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) ("rtk_get_fw_project_id: opcode %d, len %d, data %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) opcode, len, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) RTKBT_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) ("rtk_get_fw_project_id: invalid len %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) p_buf -= len + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) } while (*p_buf != 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static void rtk_get_patch_entry(uint8_t * epatch_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) struct rtk_epatch_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) uint32_t svn_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) uint32_t coex_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) uint32_t tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) uint16_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) struct rtk_epatch *epatch_info = (struct rtk_epatch *)epatch_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) epatch_info->number_of_total_patch =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) le16_to_cpu(epatch_info->number_of_total_patch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) RTKBT_DBG("fw_version = 0x%x", le32_to_cpu(epatch_info->fw_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) RTKBT_DBG("number_of_total_patch = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) epatch_info->number_of_total_patch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) /* get right epatch entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) for (i = 0; i < epatch_info->number_of_total_patch; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (get_unaligned_le16(epatch_buf + 14 + 2 * i) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) gEVersion + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) entry->chipID = gEVersion + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) entry->patch_length = get_unaligned_le16(epatch_buf +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 14 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 2 * epatch_info->number_of_total_patch +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 2 * i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) entry->start_offset = get_unaligned_le32(epatch_buf +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 14 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 4 * epatch_info-> number_of_total_patch +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 4 * i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (i >= epatch_info->number_of_total_patch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) entry->patch_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) entry->start_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) RTKBT_ERR("No corresponding patch found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) svn_ver = get_unaligned_le32(epatch_buf +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) entry->start_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) entry->patch_length - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) coex_ver = get_unaligned_le32(epatch_buf +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) entry->start_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) entry->patch_length - 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) RTKBT_DBG("chipID %d", entry->chipID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) RTKBT_DBG("patch_length 0x%04x", entry->patch_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) RTKBT_DBG("start_offset 0x%08x", entry->start_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) RTKBT_DBG("Svn version: %8d", svn_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) tmp = ((coex_ver >> 16) & 0x7ff) + (coex_ver >> 27) * 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) RTKBT_DBG("Coexistence: BTCOEX_20%06d-%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) tmp, (coex_ver & 0xffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) int bachk(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (strlen(str) != 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) while (*str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (!isxdigit(*str++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (!isxdigit(*str++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (*str == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (*str++ != ':')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) static int request_bdaddr(u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) u8 tbuf[BDADDR_STRING_LEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) loff_t pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) file = filp_open(BDADDR_FILE, O_RDONLY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (IS_ERR(file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (!S_ISREG(file_inode(file)->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) size = i_size_read(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (size <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (size > BDADDR_STRING_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) size = BDADDR_STRING_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) memset(tbuf, 0, sizeof(tbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) RTKBT_INFO("size = %d", size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) rc = kernel_read(file, tbuf, size, &pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) rc = kernel_read(file, 0, tbuf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) fput(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (rc != size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if (rc >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (bachk(tbuf) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) str = tbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) for (i = 5; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) buf[i] = simple_strtol(str, NULL, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) str += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static u8 *load_config(dev_data *dev_entry, int *length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) patch_info *patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) const char *config_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) u8 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) u16 config_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) u16 dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) u8 tmp_buf[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) int file_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) struct cfg_list_item *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) struct list_head *pos, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) u8 chip_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) config_lists_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) patch_entry = dev_entry->patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) config_name = patch_entry->config_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) udev = dev_entry->udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) chip_type = patch_entry->chip_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) RTKBT_INFO("config filename %s", config_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) result = request_firmware(&fw, config_name, &udev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) file_sz = fw->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) buf = (u8 *)fw->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) /* Load extra configs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) config_file_proc(EXTRA_CONFIG_FILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) list_for_each_safe(pos, next, &list_extracfgs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) n = list_entry(pos, struct cfg_list_item, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) RTKBT_INFO("extra cfg: ofs %04x, len %u", n->offset, n->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) /* Load extra bdaddr config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) memset(tmp_buf, 0, sizeof(tmp_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) result = request_bdaddr(tmp_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (result > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) n = kzalloc(sizeof(*n) + 6, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) n->offset = get_mac_offset(patch_entry->chip_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) n->len = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) memcpy(n->data, tmp_buf, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) list_add_tail(&n->list, &list_extracfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) RTKBT_WARN("Couldn't alloc mem for bdaddr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (result == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) RTKBT_WARN("no bdaddr file %s", BDADDR_FILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) RTKBT_WARN("invalid customer bdaddr %d", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) RTKBT_INFO("Origin cfg len %u", (u16)file_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) util_hexdump((const u8 *)buf, file_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) result = rtk_parse_config_file(buf, file_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) RTKBT_ERR("Parse config file error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) merge_configs(&list_configs, &list_extracfgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) /* Calculate the config_len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) config_len = 4; /* magic word length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) config_len += 2; /* data length field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) dlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) list_for_each_safe(pos, next, &list_configs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) n = list_entry(pos, struct cfg_list_item, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) switch (n->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) case 0x003c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) case 0x0030:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) case 0x0044:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) if (is_mac(chip_type, n->offset) && n->len == 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) char s[18];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) sprintf(s, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) n->data[5], n->data[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) n->data[3], n->data[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) n->data[1], n->data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) RTKBT_INFO("bdaddr ofs %04x, %s", n->offset, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) config_len += (3 + n->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) dlen += (3 + n->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) buf = kzalloc(config_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) RTKBT_ERR("Couldn't alloc buf for configs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) /* Save configs to a buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) memcpy(buf, cfg_magic, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) buf[4] = dlen & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) buf[5] = (dlen >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) p = buf + 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) list_for_each_safe(pos, next, &list_configs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) n = list_entry(pos, struct cfg_list_item, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) p[0] = n->offset & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) p[1] = (n->offset >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) p[2] = n->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) memcpy(p + 3, n->data, n->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) p += (3 + n->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) RTKBT_INFO("New cfg len %u", config_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) util_hexdump((const u8 *)buf, config_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) *length = config_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) config_lists_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) int load_firmware(dev_data * dev_entry, uint8_t ** buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) patch_info *patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) char *fw_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) int fw_len = 0, ret_val = 0, config_len = 0, buf_len = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) uint8_t *buf = NULL, *config_file_buf = NULL, *epatch_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) uint8_t proj_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) uint8_t need_download_fw = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) uint16_t lmp_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) struct rtk_epatch_entry current_entry = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) RTKBT_DBG("load_firmware start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) udev = dev_entry->udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) patch_entry = dev_entry->patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) lmp_version = patch_entry->lmp_sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) RTKBT_DBG("lmp_version = 0x%04x", lmp_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) config_file_buf = load_config(dev_entry, &config_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) fw_name = patch_entry->patch_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) RTKBT_ERR("fw name is %s", fw_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) ret_val = request_firmware(&fw, fw_name, &udev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) fw_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) kfree(config_file_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) config_file_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) goto fw_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) epatch_buf = kzalloc(fw->size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) if (NULL == epatch_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) goto alloc_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) memcpy(epatch_buf, fw->data, fw->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) buf_len = fw->size + config_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (lmp_version == ROM_LMP_8723a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) RTKBT_DBG("This is 8723a, use old patch style!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) if (memcmp(epatch_buf, RTK_EPATCH_SIGNATURE, 8) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) RTKBT_ERR("8723a Check signature error!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) need_download_fw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (!(buf = kzalloc(buf_len, GFP_KERNEL))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) RTKBT_ERR("Can't alloc memory for fw&config");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) buf_len = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) RTKBT_DBG("8723a, fw copy direct");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) memcpy(buf, epatch_buf, fw->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (config_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) memcpy(&buf[buf_len - config_len],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) config_file_buf, config_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) RTKBT_ERR("This is not 8723a, use new patch style!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) /* Get version from ROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) gEVersion = rtk_get_eversion(dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) RTKBT_DBG("%s: New gEVersion %d", __func__, gEVersion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) if (gEVersion == 0xFE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) RTKBT_ERR("%s: Read ROM version failure", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) need_download_fw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) fw_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) goto alloc_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) /* check Signature and Extension Section Field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) if ((memcmp(epatch_buf, RTK_EPATCH_SIGNATURE, 8) != 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) memcmp(epatch_buf + buf_len - config_len - 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) Extension_Section_SIGNATURE, 4) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) RTKBT_ERR("Check SIGNATURE error! do not download fw");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) need_download_fw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) proj_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) rtk_get_fw_project_id(epatch_buf + buf_len -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) config_len - 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (lmp_version != project_id[proj_id]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) RTKBT_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) ("lmp_version is %x, project_id is %x, does not match!!!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) lmp_version, project_id[proj_id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) need_download_fw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) RTKBT_DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) ("lmp_version is %x, project_id is %x, match!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) lmp_version, project_id[proj_id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) rtk_get_patch_entry(epatch_buf, ¤t_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (current_entry.patch_length == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) goto alloc_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) buf_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) current_entry.patch_length + config_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) RTKBT_DBG("buf_len = 0x%x", buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (!(buf = kzalloc(buf_len, GFP_KERNEL))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) RTKBT_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) ("Can't alloc memory for multi fw&config");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) buf_len = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) memcpy(buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) epatch_buf +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) current_entry.start_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) current_entry.patch_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) memcpy(buf + current_entry.patch_length - 4, epatch_buf + 8, 4); /*fw version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (config_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) memcpy(&buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) [buf_len - config_len],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) config_file_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) config_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) RTKBT_DBG("fw:%s exists, config file:%s exists",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) (buf_len > 0) ? "" : "not", (config_len > 0) ? "" : "not");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) if (buf && (buf_len > 0) && (need_download_fw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) fw_len = buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) *buff = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) RTKBT_DBG("load_firmware done");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) alloc_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) if (epatch_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) kfree(epatch_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) if (config_file_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) kfree(config_file_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) fw_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) if (fw_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) return fw_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) void init_xdata(xchange_data * xdata, dev_data * dev_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) memset(xdata, 0, sizeof(xchange_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) xdata->dev_entry = dev_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) xdata->pipe_in = usb_rcvintpipe(dev_entry->udev, INTR_EP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) xdata->pipe_out = usb_sndctrlpipe(dev_entry->udev, CTRL_EP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) xdata->send_pkt = kzalloc(PKT_LEN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) xdata->rcv_pkt = kzalloc(PKT_LEN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) xdata->cmd_hdr = (struct hci_command_hdr *)(xdata->send_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) xdata->evt_hdr = (struct hci_event_hdr *)(xdata->rcv_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) xdata->cmd_cmp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) (struct hci_ev_cmd_complete *)(xdata->rcv_pkt + EVT_HDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) xdata->req_para = xdata->send_pkt + CMD_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) xdata->rsp_para = xdata->rcv_pkt + EVT_HDR_LEN + CMD_CMP_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) int check_fw_version(xchange_data * xdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) struct hci_rp_read_local_version *read_ver_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) patch_info *patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) int retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) /* Ensure that the first cmd is hci reset after system suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) * or system reboot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) send_reset_command(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) get_ver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) xdata->cmd_hdr->opcode = cpu_to_le16(HCI_OP_READ_LOCAL_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) xdata->cmd_hdr->plen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) xdata->pkt_len = CMD_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) ret_val = send_hci_cmd(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) RTKBT_ERR("%s: Failed to send HCI command.", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) goto version_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) ret_val = rcv_hci_evt(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) RTKBT_ERR("%s: Failed to receive HCI event.", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) goto version_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) patch_entry = xdata->dev_entry->patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) read_ver_rsp = (struct hci_rp_read_local_version *)(xdata->rsp_para);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) read_ver_rsp->lmp_subver = le16_to_cpu(read_ver_rsp->lmp_subver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) read_ver_rsp->hci_rev = le16_to_cpu(read_ver_rsp->hci_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) read_ver_rsp->manufacturer = le16_to_cpu(read_ver_rsp->manufacturer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) RTKBT_DBG("read_ver_rsp->lmp_subver = 0x%x", read_ver_rsp->lmp_subver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) RTKBT_DBG("read_ver_rsp->hci_rev = 0x%x", read_ver_rsp->hci_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) RTKBT_DBG("patch_entry->lmp_sub = 0x%x", patch_entry->lmp_sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (patch_entry->lmp_sub != read_ver_rsp->lmp_subver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) version_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (ret_val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) send_reset_command(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) if (retry < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) goto get_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) uint8_t rtk_get_eversion(dev_data * dev_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) struct rtk_eversion_evt *eversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) patch_info *patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) int ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) xchange_data *xdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) RTKBT_DBG("%s: gEVersion %d", __func__, gEVersion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) if (gEVersion != 0xFF && gEVersion != 0xFE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) RTKBT_DBG("gEVersion != 0xFF, return it directly!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) return gEVersion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) xdata = kzalloc(sizeof(xchange_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (NULL == xdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) ret_val = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) RTKBT_DBG("NULL == xdata");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) init_xdata(xdata, dev_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) xdata->cmd_hdr->opcode = cpu_to_le16(HCI_VENDOR_READ_RTK_ROM_VERISION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) xdata->cmd_hdr->plen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) xdata->pkt_len = CMD_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) ret_val = send_hci_cmd(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) RTKBT_ERR("Failed to send read RTK rom version cmd.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) ret_val = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) goto version_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) ret_val = rcv_hci_evt(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) RTKBT_ERR("Failed to receive HCI event for rom version.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) ret_val = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) goto version_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) patch_entry = xdata->dev_entry->patch_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) eversion = (struct rtk_eversion_evt *)(xdata->rsp_para);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) RTKBT_DBG("eversion->status = 0x%x, eversion->version = 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) eversion->status, eversion->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) if (eversion->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) //global_eversion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) ret_val = eversion->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) //global_eversion = eversion->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) version_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) if (xdata != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (xdata->send_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) kfree(xdata->send_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (xdata->rcv_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) kfree(xdata->rcv_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) kfree(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) int download_data(xchange_data * xdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) download_cp *cmd_para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) download_rp *evt_para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) uint8_t *pcur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) int pkt_len, frag_num, frag_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) int i, ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) RTKBT_DBG("download_data start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) cmd_para = (download_cp *) xdata->req_para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) evt_para = (download_rp *) xdata->rsp_para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) pcur = xdata->fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) pkt_len = CMD_HDR_LEN + sizeof(download_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) frag_num = xdata->fw_len / PATCH_SEG_MAX + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) frag_len = PATCH_SEG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) for (i = 0; i < frag_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) if (i > 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) j = (i & 0x7f) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) j = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) cmd_para->index = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) if (i == (frag_num - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) cmd_para->index |= DATA_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) frag_len = xdata->fw_len % PATCH_SEG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) pkt_len -= (PATCH_SEG_MAX - frag_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) xdata->cmd_hdr->opcode = cpu_to_le16(DOWNLOAD_OPCODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) xdata->cmd_hdr->plen = sizeof(uint8_t) + frag_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) xdata->pkt_len = pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) memcpy(cmd_para->data, pcur, frag_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) ret_val = send_hci_cmd(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) ret_val = rcv_hci_evt(xdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (0 != evt_para->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) pcur += PATCH_SEG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) RTKBT_DBG("download_data done");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) return xdata->fw_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) int send_hci_cmd(xchange_data * xdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) ret_val = usb_control_msg(xdata->dev_entry->udev, xdata->pipe_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 0, USB_TYPE_CLASS, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) (void *)(xdata->send_pkt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) xdata->pkt_len, MSG_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if (ret_val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) RTKBT_ERR("%s; failed to send ctl msg for hci cmd, err %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) __func__, ret_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) int rcv_hci_evt(xchange_data * xdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) int ret_len = 0, ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) int i; // Added by Realtek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) // **************************** Modifed by Realtek (begin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) for (i = 0; i < 5; i++) // Try to send USB interrupt message 5 times.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) ret_val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) usb_interrupt_msg(xdata->dev_entry->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) xdata->pipe_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) (void *)(xdata->rcv_pkt), PKT_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) &ret_len, MSG_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) if (ret_val >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) // **************************** Modifed by Realtek (end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) RTKBT_ERR("%s; no usb intr msg for hci event, err %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) __func__, ret_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) if (CMD_CMP_EVT == xdata->evt_hdr->evt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) if (xdata->cmd_hdr->opcode == xdata->cmd_cmp->opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) return ret_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) void print_acl(struct sk_buff *skb, int dataOut)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) #if PRINT_ACL_DATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) uint wlength = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) uint icount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) u16 *handle = (u16 *) (skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) u16 dataLen = *(handle + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) u8 *acl_data = (u8 *) (skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) //if (0==dataOut)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) printk("%d handle:%04x,len:%d,", dataOut, *handle, dataLen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) //else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) // printk("In handle:%04x,len:%d,",*handle,dataLen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) /* for(icount=4;(icount<wlength)&&(icount<32);icount++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) printk("%02x ",*(acl_data+icount) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) void print_command(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) #if PRINT_CMD_EVENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) uint wlength = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) uint icount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) u16 *opcode = (u16 *) (skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) u8 *cmd_data = (u8 *) (skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) u8 paramLen = *(cmd_data + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) switch (*opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) case HCI_OP_INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) printk("HCI_OP_INQUIRY");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) case HCI_OP_INQUIRY_CANCEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) printk("HCI_OP_INQUIRY_CANCEL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) case HCI_OP_EXIT_PERIODIC_INQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) printk("HCI_OP_EXIT_PERIODIC_INQ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) case HCI_OP_CREATE_CONN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) printk("HCI_OP_CREATE_CONN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) case HCI_OP_DISCONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) printk("HCI_OP_DISCONNECT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) case HCI_OP_CREATE_CONN_CANCEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) printk("HCI_OP_CREATE_CONN_CANCEL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) case HCI_OP_ACCEPT_CONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) printk("HCI_OP_ACCEPT_CONN_REQ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) case HCI_OP_REJECT_CONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) printk("HCI_OP_REJECT_CONN_REQ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) case HCI_OP_AUTH_REQUESTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) printk("HCI_OP_AUTH_REQUESTED");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) case HCI_OP_SET_CONN_ENCRYPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) printk("HCI_OP_SET_CONN_ENCRYPT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) case HCI_OP_REMOTE_NAME_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) printk("HCI_OP_REMOTE_NAME_REQ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) case HCI_OP_READ_REMOTE_FEATURES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) printk("HCI_OP_READ_REMOTE_FEATURES");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) case HCI_OP_SNIFF_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) printk("HCI_OP_SNIFF_MODE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) case HCI_OP_EXIT_SNIFF_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) printk("HCI_OP_EXIT_SNIFF_MODE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) case HCI_OP_SWITCH_ROLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) printk("HCI_OP_SWITCH_ROLE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) case HCI_OP_SNIFF_SUBRATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) printk("HCI_OP_SNIFF_SUBRATE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) case HCI_OP_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) printk("HCI_OP_RESET");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) printk("CMD");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) printk(":%04x,len:%d,", *opcode, paramLen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) for (icount = 3; (icount < wlength) && (icount < 24); icount++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) printk("%02x ", *(cmd_data + icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) void print_event(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) #if PRINT_CMD_EVENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) uint wlength = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) uint icount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) u8 *opcode = (u8 *) (skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) u8 paramLen = *(opcode + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) switch (*opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) case HCI_EV_INQUIRY_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) printk("HCI_EV_INQUIRY_COMPLETE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) case HCI_EV_INQUIRY_RESULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) printk("HCI_EV_INQUIRY_RESULT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) case HCI_EV_CONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) printk("HCI_EV_CONN_COMPLETE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) case HCI_EV_CONN_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) printk("HCI_EV_CONN_REQUEST");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) case HCI_EV_DISCONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) printk("HCI_EV_DISCONN_COMPLETE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) case HCI_EV_AUTH_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) printk("HCI_EV_AUTH_COMPLETE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) case HCI_EV_REMOTE_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) printk("HCI_EV_REMOTE_NAME");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) case HCI_EV_ENCRYPT_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) printk("HCI_EV_ENCRYPT_CHANGE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) printk("HCI_EV_CHANGE_LINK_KEY_COMPLETE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) case HCI_EV_REMOTE_FEATURES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) printk("HCI_EV_REMOTE_FEATURES");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) case HCI_EV_REMOTE_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) printk("HCI_EV_REMOTE_VERSION");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) case HCI_EV_QOS_SETUP_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) printk("HCI_EV_QOS_SETUP_COMPLETE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) case HCI_EV_CMD_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) printk("HCI_EV_CMD_COMPLETE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) case HCI_EV_CMD_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) printk("HCI_EV_CMD_STATUS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) case HCI_EV_ROLE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) printk("HCI_EV_ROLE_CHANGE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) case HCI_EV_NUM_COMP_PKTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) printk("HCI_EV_NUM_COMP_PKTS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) case HCI_EV_MODE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) printk("HCI_EV_MODE_CHANGE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) case HCI_EV_PIN_CODE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) printk("HCI_EV_PIN_CODE_REQ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) case HCI_EV_LINK_KEY_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) printk("HCI_EV_LINK_KEY_REQ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) case HCI_EV_LINK_KEY_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) printk("HCI_EV_LINK_KEY_NOTIFY");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) case HCI_EV_CLOCK_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) printk("HCI_EV_CLOCK_OFFSET");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) case HCI_EV_PKT_TYPE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) printk("HCI_EV_PKT_TYPE_CHANGE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) case HCI_EV_PSCAN_REP_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) printk("HCI_EV_PSCAN_REP_MODE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) printk("HCI_EV_INQUIRY_RESULT_WITH_RSSI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) case HCI_EV_REMOTE_EXT_FEATURES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) printk("HCI_EV_REMOTE_EXT_FEATURES");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) case HCI_EV_SYNC_CONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) printk("HCI_EV_SYNC_CONN_COMPLETE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) case HCI_EV_SYNC_CONN_CHANGED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) printk("HCI_EV_SYNC_CONN_CHANGED");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) case HCI_EV_SNIFF_SUBRATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) printk("HCI_EV_SNIFF_SUBRATE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) case HCI_EV_EXTENDED_INQUIRY_RESULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) printk("HCI_EV_EXTENDED_INQUIRY_RESULT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) case HCI_EV_IO_CAPA_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) printk("HCI_EV_IO_CAPA_REQUEST");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) case HCI_EV_SIMPLE_PAIR_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) printk("HCI_EV_SIMPLE_PAIR_COMPLETE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) case HCI_EV_REMOTE_HOST_FEATURES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) printk("HCI_EV_REMOTE_HOST_FEATURES");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) printk("event");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) printk(":%02x,len:%d,", *opcode, paramLen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) for (icount = 2; (icount < wlength) && (icount < 24); icount++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) printk("%02x ", *(opcode + icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);