Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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, &current_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);