Path: blob/next/external/cache/sources/rtk_hciattach/hciattach_rtk.c
8659 views
/*1* Copyright (C) 2013 Realtek Semiconductor Corp.2*3* This program is free software; you can redistribute it and/or modify4* it under the terms of the GNU General Public License as published by5* the Free Software Foundation; either version 2 of the License, or6* (at your option) any later version.7*8* This program is distributed in the hope that it will be useful,9* but WITHOUT ANY WARRANTY; without even the implied warranty of10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11* GNU General Public License for more details.12*/1314#ifdef HAVE_CONFIG_H15#include <config.h>16#endif1718#include <stdio.h>19#include <errno.h>20#include <unistd.h>21#include <stdlib.h>22#include <termios.h>23#include <time.h>24#include <sys/time.h>25#include <sys/types.h>26#include <sys/param.h>27#include <sys/ioctl.h>28#include <sys/socket.h>29#include <sys/uio.h>30#include <sys/stat.h>31#include <fcntl.h>32#include <signal.h>33#include <stdint.h>34#include <string.h>35#include <endian.h>36#include <byteswap.h>37#include <netinet/in.h>38#include <poll.h>39#include <sys/timerfd.h>40#include <sys/epoll.h>4142#include "rtb_fwc.h"43#include "hciattach.h"44#include "hciattach_h4.h"4546#define RTK_VERSION "3.1.bca84ed.20190715-143612"4748#define TIMESTAMP_PR4950#define MAX_EVENTS 105152/* #define SERIAL_NONBLOCK_READ */5354#ifdef SERIAL_NONBLOCK_READ55#define FD_BLOCK 056#define FD_NONBLOCK 157#endif5859/* #define RTL_8703A_SUPPORT */60/* #define RTL8723DSH4_UART_HWFLOWC */ /* 8723DS H4 special */6162uint8_t DBG_ON = 1;6364#define HCI_EVENT_HDR_SIZE 265/* #define RTK_PATCH_LENGTH_MAX 24576 */ //24*102466#define RTB_PATCH_LENGTH_MAX (40 * 1024)67#define PATCH_DATA_FIELD_MAX_SIZE 2526869#define HCI_CMD_READ_BD_ADDR 0x100970#define HCI_VENDOR_CHANGE_BAUD 0xfc1771#define HCI_VENDOR_READ_ROM_VER 0xfc6d72#define HCI_CMD_READ_LOCAL_VER 0x100173#define HCI_VENDOR_READ_CHIP_TYPE 0xfc6174#define HCI_CMD_RESET 0x0c037576/* HCI data types */77#define H5_ACK_PKT 0x0078#define HCI_COMMAND_PKT 0x0179#define HCI_ACLDATA_PKT 0x0280#define HCI_SCODATA_PKT 0x0381#define HCI_EVENT_PKT 0x0482#define H5_VDRSPEC_PKT 0x0E83#define H5_LINK_CTL_PKT 0x0F8485#define H5_HDR_SEQ(hdr) ((hdr)[0] & 0x07)86#define H5_HDR_ACK(hdr) (((hdr)[0] >> 3) & 0x07)87#define H5_HDR_CRC(hdr) (((hdr)[0] >> 6) & 0x01)88#define H5_HDR_RELIABLE(hdr) (((hdr)[0] >> 7) & 0x01)89#define H5_HDR_PKT_TYPE(hdr) ((hdr)[1] & 0x0f)90#define H5_HDR_LEN(hdr) ((((hdr)[1] >> 4) & 0xff) + ((hdr)[2] << 4))91#define H5_HDR_SIZE 49293struct sk_buff {94uint32_t max_len;95uint32_t data_len;96uint8_t *data;97};9899struct hci_ev_cmd_complete {100uint8_t ncmd;101uint16_t opcode;102} __attribute__ ((packed));103104#define OP_H5_SYNC 0x01105#define OP_H5_CONFIG 0x02106#define OP_ROM_VER ((1 << 24) | HCI_VENDOR_READ_ROM_VER)107#define OP_LMP_VER ((1 << 24) | HCI_CMD_READ_LOCAL_VER)108#define OP_CHIP_TYPE ((1 << 24) | HCI_VENDOR_READ_CHIP_TYPE)109#define OP_SET_BAUD ((1 << 24) | HCI_VENDOR_CHANGE_BAUD)110#define OP_HCI_RESET ((1 << 24) | HCI_CMD_RESET)111112struct rtb_struct rtb_cfg;113114/* bite reverse in bytes115* 00000001 -> 10000000116* 00000100 -> 00100000117*/118const uint8_t byte_rev_table[256] = {1190x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,1200x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,1210x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,1220x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,1230x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,1240x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,1250x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,1260x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,1270x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,1280x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,1290x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,1300x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,1310x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,1320x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,1330x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,1340x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,1350x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,1360x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,1370x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,1380x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,1390x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,1400x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,1410x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,1420x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,1430x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,1440x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,1450x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,1460x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,1470x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,1480x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,1490x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,1500x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,151};152153static __inline uint8_t bit_rev8(uint8_t byte)154{155return byte_rev_table[byte];156}157158static __inline uint16_t bit_rev16(uint16_t x)159{160return (bit_rev8(x & 0xff) << 8) | bit_rev8(x >> 8);161}162163static const uint16_t crc_table[] = {1640x0000, 0x1081, 0x2102, 0x3183,1650x4204, 0x5285, 0x6306, 0x7387,1660x8408, 0x9489, 0xa50a, 0xb58b,1670xc60c, 0xd68d, 0xe70e, 0xf78f168};169170/* Initialise the crc calculator */171#define H5_CRC_INIT(x) x = 0xffff172173static __inline struct sk_buff *skb_alloc(unsigned int len)174{175struct sk_buff *skb = NULL;176177if ((skb = malloc(len + sizeof(*skb)))) {178skb->max_len = len;179skb->data_len = 0;180skb->data = ((uint8_t *)skb) + sizeof(*skb);181} else {182RS_ERR("Allocate skb fails!");183skb = NULL;184return NULL;185}186memset(skb->data, 0, len);187return skb;188}189190static __inline void skb_free(struct sk_buff *skb)191{192free(skb);193return;194}195196/*197* Add data to a buffer198* This function extends the used data area of the buffer.199*/200static uint8_t *skb_put(struct sk_buff *skb, uint32_t len)201{202uint32_t old_len = skb->data_len;203204if ((skb->data_len + len) > (skb->max_len)) {205RS_ERR("Buffer too small");206exit(EXIT_FAILURE);207}208skb->data_len += len;209return (skb->data + old_len);210}211212/*213* Remove end from a buffer214* Cut the length of a buffer down by removing data from the tail215*/216static void skb_trim(struct sk_buff *skb, uint32_t len)217{218if (skb->data_len > len) {219skb->data_len = len;220} else {221RS_ERR("Trim error, data_len %u < len %u", skb->data_len, len);222}223}224225/*226* Remove data from the start of a buffer227* This function removes data from the start of a buffer.228* A pointer to the next data in the buffer is returned229*/230static uint8_t *skb_pull(struct sk_buff *skb, uint32_t len)231{232if (len > skb->data_len) {233RS_ERR("Pull error, data_len %u < len %u", skb->data_len, len);234exit(EXIT_FAILURE);235}236skb->data_len -= len;237skb->data += len;238return skb->data;239}240241/**242* Add "d" into crc scope, caculate the new crc value243*244* @param crc crc data245* @param d one byte data246*/247static void h5_crc_update(uint16_t * crc, uint8_t d)248{249uint16_t reg = *crc;250251reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];252reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];253254*crc = reg;255}256257struct __una_u16 {258uint16_t x;259};260static __inline uint16_t __get_unaligned_cpu16(const void *p)261{262const struct __una_u16 *ptr = (const struct __una_u16 *)p;263return ptr->x;264}265266static __inline uint16_t get_unaligned_be16(const void *p)267{268return __get_unaligned_cpu16((const uint8_t *)p);269}270271/*272* Get crc data.273*/274static uint16_t h5_get_crc(struct rtb_struct * h5)275{276uint16_t crc = 0;277uint8_t *data = h5->rx_skb->data + h5->rx_skb->data_len - 2;278279crc = data[1] + (data[0] << 8);280return crc;281/* return get_unaligned_be16(&h5->rx_skb->data[h5->rx_skb->data_len - 2]); */282}283284/*285* Add 0xc0 to buffer.286*/287static void h5_slip_msgdelim(struct sk_buff *skb)288{289const char pkt_delim = 0xc0;290memcpy(skb_put(skb, 1), &pkt_delim, 1);291}292293/*294* Encode one byte in h5 proto295* 0xc0 -> 0xdb, 0xdc296* 0xdb -> 0xdb, 0xdd297* 0x11 -> 0xdb, 0xde298* 0x13 -> 0xdb, 0xdf299* others will not change300*/301static void h5_slip_one_byte(struct sk_buff *skb, uint8_t c)302{303const uint8_t esc_c0[2] = { 0xdb, 0xdc };304const uint8_t esc_db[2] = { 0xdb, 0xdd };305const uint8_t esc_11[2] = { 0xdb, 0xde };306const uint8_t esc_13[2] = { 0xdb, 0xdf };307308switch (c) {309case 0xc0:310memcpy(skb_put(skb, 2), &esc_c0, 2);311break;312313case 0xdb:314memcpy(skb_put(skb, 2), &esc_db, 2);315break;316317case 0x11:318memcpy(skb_put(skb, 2), &esc_11, 2);319break;320321case 0x13:322memcpy(skb_put(skb, 2), &esc_13, 2);323break;324325default:326memcpy(skb_put(skb, 1), &c, 1);327break;328}329}330331/*332* Decode one byte in h5 proto333* 0xdb, 0xdc -> 0xc0334* 0xdb, 0xdd -> 0xdb335* 0xdb, 0xde -> 0x11336* 0xdb, 0xdf -> 0x13337* others will not change338*/339static void h5_unslip_one_byte(struct rtb_struct * h5, unsigned char byte)340{341const uint8_t c0 = 0xc0, db = 0xdb;342const uint8_t oof1 = 0x11, oof2 = 0x13;343344if (H5_ESCSTATE_NOESC == h5->rx_esc_state) {345if (0xdb == byte) {346h5->rx_esc_state = H5_ESCSTATE_ESC;347} else {348memcpy(skb_put(h5->rx_skb, 1), &byte, 1);349/* Check Pkt Header's CRC enable bit */350if ((h5->rx_skb->data[0] & 0x40) != 0 &&351h5->rx_state != H5_W4_CRC) {352h5_crc_update(&h5->message_crc, byte);353}354h5->rx_count--;355}356} else if (H5_ESCSTATE_ESC == h5->rx_esc_state) {357switch (byte) {358case 0xdc:359memcpy(skb_put(h5->rx_skb, 1), &c0, 1);360if ((h5->rx_skb->data[0] & 0x40) != 0 &&361h5->rx_state != H5_W4_CRC)362h5_crc_update(&h5->message_crc, 0xc0);363h5->rx_esc_state = H5_ESCSTATE_NOESC;364h5->rx_count--;365break;366367case 0xdd:368memcpy(skb_put(h5->rx_skb, 1), &db, 1);369if ((h5->rx_skb->data[0] & 0x40) != 0 &&370h5->rx_state != H5_W4_CRC)371h5_crc_update(&h5->message_crc, 0xdb);372h5->rx_esc_state = H5_ESCSTATE_NOESC;373h5->rx_count--;374break;375376case 0xde:377memcpy(skb_put(h5->rx_skb, 1), &oof1, 1);378if ((h5->rx_skb->data[0] & 0x40) != 0 &&379h5->rx_state != H5_W4_CRC)380h5_crc_update(&h5->message_crc, oof1);381h5->rx_esc_state = H5_ESCSTATE_NOESC;382h5->rx_count--;383break;384385case 0xdf:386memcpy(skb_put(h5->rx_skb, 1), &oof2, 1);387if ((h5->rx_skb->data[0] & 0x40) != 0 &&388h5->rx_state != H5_W4_CRC)389h5_crc_update(&h5->message_crc, oof2);390h5->rx_esc_state = H5_ESCSTATE_NOESC;391h5->rx_count--;392break;393394default:395RS_ERR("Error: Invalid byte %02x after esc byte", byte);396skb_free(h5->rx_skb);397h5->rx_skb = NULL;398h5->rx_state = H5_W4_PKT_DELIMITER;399h5->rx_count = 0;400break;401}402}403}404405/*406* Prepare h5 packet407* Refer to Core Spec Vol 4, Part D408* Three-wire UART Transport Layer: 4 PACKET HEADER409*/410static struct sk_buff *h5_prepare_pkt(struct rtb_struct * h5, uint8_t *data,411int len, int pkt_type)412{413struct sk_buff *nskb;414uint8_t hdr[4];415uint16_t H5_CRC_INIT(h5_txmsg_crc);416int rel, i;417418switch (pkt_type) {419case HCI_ACLDATA_PKT:420case HCI_COMMAND_PKT:421case HCI_EVENT_PKT:422rel = 1; /* reliable */423break;424425case H5_ACK_PKT:426case H5_VDRSPEC_PKT:427case H5_LINK_CTL_PKT:428rel = 0; /* unreliable */429break;430431default:432RS_ERR("Unknown packet type");433return NULL;434}435436/* Max len of packet: (len + 4(h5 hdr) + 2(crc))*2437* Because bytes 0xc0 and 0xdb are escaped, worst case is that the438* packet is only made of 0xc0 and 0xdb439* The additional 2-octets are 0xc0 delimiters at start and end of each440* packet.441*/442nskb = skb_alloc((len + 6) * 2 + 2);443if (!nskb)444return NULL;445446/* Add SLIP start byte: 0xc0 */447h5_slip_msgdelim(nskb);448/* Set ack number in SLIP header */449hdr[0] = h5->rxseq_txack << 3;450h5->is_txack_req = 0;451452/* RS_DBG("Request packet no(%u) to card", h5->rxseq_txack); */453/* RS_DBG("Sending packet with seqno %u and wait %u", h5->msgq_txseq,454* h5->rxseq_txack);455*/456if (rel) {457/* Set reliable bit and seq number */458hdr[0] |= 0x80 + h5->msgq_txseq;459/* RS_DBG("Sending packet with seqno(%u)", h5->msgq_txseq); */460++(h5->msgq_txseq);461h5->msgq_txseq = (h5->msgq_txseq) & 0x07;462}463/* Set DIC Present bit */464if (h5->use_crc)465hdr[0] |= 0x40;466467/* Set packet type and payload length */468hdr[1] = ((len << 4) & 0xff) | pkt_type;469hdr[2] = (uint8_t) (len >> 4);470/* Set header checksum */471hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);472473/* Encode h5 header */474for (i = 0; i < 4; i++) {475h5_slip_one_byte(nskb, hdr[i]);476477if (h5->use_crc)478h5_crc_update(&h5_txmsg_crc, hdr[i]);479}480481/* Encode payload */482for (i = 0; i < len; i++) {483h5_slip_one_byte(nskb, data[i]);484485if (h5->use_crc)486h5_crc_update(&h5_txmsg_crc, data[i]);487}488489/* Encode CRC */490if (h5->use_crc) {491h5_txmsg_crc = bit_rev16(h5_txmsg_crc);492h5_slip_one_byte(nskb, (uint8_t) ((h5_txmsg_crc >> 8) & 0x00ff));493h5_slip_one_byte(nskb, (uint8_t) (h5_txmsg_crc & 0x00ff));494}495/* Add 0xc0 at the end of the packet */496h5_slip_msgdelim(nskb);497498return nskb;499}500501/*502* Remove controller acked packet from host unacked lists503*/504/* static void h5_remove_acked_pkt(struct rtb_struct * h5)505* {506* int pkts_to_be_removed = 0;507* int seqno = 0;508* int i = 0;509*510* seqno = h5->msgq_txseq;511* // pkts_to_be_removed = GetListLength(h5->unacked);512*513* while (pkts_to_be_removed) {514* if (h5->rxack == seqno)515* break;516*517* pkts_to_be_removed--;518* seqno = (seqno - 1) & 0x07;519* }520*521* if (h5->rxack != seqno) {522* RS_DBG("Peer acked invalid packet");523* }524* // skb_queue_walk_safe(&h5->unack, skb, tmp)525* // remove ack'ed packet from h5->unack queue526* for (i = 0; i < 5; ++i) {527* if (i >= pkts_to_be_removed)528* break;529* i++;530* //__skb_unlink(skb, &h5->unack);531* //skb_free(skb);532* }533*534* // if (skb_queue_empty(&h5->unack))535* // del_timer(&h5->th5);536* // spin_unlock_irqrestore(&h5->unack.lock, flags);537*538* if (i != pkts_to_be_removed)539* RS_DBG("Removed only (%u) out of (%u) pkts", i,540* pkts_to_be_removed);541* }542*/543544/*545* Send host ack.546*/547static void rtb_send_ack(int fd)548{549int len;550struct sk_buff *nskb = h5_prepare_pkt(&rtb_cfg, NULL, 0, H5_ACK_PKT);551552len = write(fd, nskb->data, nskb->data_len);553if (len != nskb->data_len)554RS_ERR("Write pure ack fails");555556skb_free(nskb);557return;558}559560/*561* Parse hci command complete event in h5 init state.562*/563static void h5_init_hci_cc(struct sk_buff *skb)564{565struct hci_ev_cmd_complete *ev = NULL;566uint16_t opcode = 0;567uint8_t status = 0;568569skb_pull(skb, HCI_EVENT_HDR_SIZE);570ev = (struct hci_ev_cmd_complete *)skb->data;571opcode = le16_to_cpu(ev->opcode);572573RS_DBG("Receive cmd complete event of command: %04x", opcode);574575skb_pull(skb, sizeof(struct hci_ev_cmd_complete));576577status = skb->data[0];578if (status) {579RS_ERR("status is %u for cmd %04x", status, opcode);580return;581}582583if (rtb_cfg.cmd_state.opcode != opcode) {584RS_ERR("%s: Received unexpected cc for cmd %04x, %04x of cc",585__func__, rtb_cfg.cmd_state.opcode, opcode);586return;587}588589rtb_cfg.cmd_state.state = CMD_STATE_SUCCESS;590591switch (opcode) {592case HCI_VENDOR_CHANGE_BAUD:593RS_INFO("Received cc of vendor change baud");594break;595case HCI_CMD_READ_BD_ADDR:596RS_INFO("BD Address: %02x:%02x:%02x:%02x:%02x:%02x",597skb->data[5], skb->data[4], skb->data[3],598skb->data[2], skb->data[1], skb->data[0]);599break;600601case HCI_CMD_READ_LOCAL_VER:602rtb_cfg.hci_ver = skb->data[1];603rtb_cfg.hci_rev = (skb->data[2] | skb->data[3] << 8);604rtb_cfg.lmp_subver = (skb->data[7] | (skb->data[8] << 8));605RS_INFO("HCI Version 0x%02x", rtb_cfg.hci_ver);606RS_INFO("HCI Revision 0x%04x", rtb_cfg.hci_rev);607RS_INFO("LMP Subversion 0x%04x", rtb_cfg.lmp_subver);608break;609610case HCI_VENDOR_READ_ROM_VER:611rtb_cfg.eversion = skb->data[1];612RS_INFO("Read ROM version %02x", rtb_cfg.eversion);613break;614615case HCI_VENDOR_READ_CHIP_TYPE:616rtb_cfg.chip_type = (skb->data[1] & 0x0f);617RS_INFO("Read chip type %02x", rtb_cfg.chip_type);618break;619default:620return;621}622623/* Count the cmd num for makeing the seq number aligned */624rtb_cfg.num_of_cmd_sent++;625}626627/*628* Parse hci command complete event in h5 post state.629*/630static void h5_post_hci_cc(struct sk_buff *skb)631{632struct hci_ev_cmd_complete *ev = NULL;633uint16_t opcode = 0;634uint8_t status = 0;635636skb_pull(skb, HCI_EVENT_HDR_SIZE);637ev = (struct hci_ev_cmd_complete *)skb->data;638opcode = le16_to_cpu(ev->opcode);639640RS_DBG("Receive cmd complete event of command: %04x", opcode);641642skb_pull(skb, sizeof(struct hci_ev_cmd_complete));643644status = skb->data[0];645if (status) {646RS_ERR("status is %u for cmd %04x", status, opcode);647return;648}649650if (rtb_cfg.cmd_state.opcode != opcode) {651RS_ERR("%s: Received unexpected cc for cmd %04x, %04x of cc",652__func__, rtb_cfg.cmd_state.opcode, opcode);653return;654}655656rtb_cfg.cmd_state.state = CMD_STATE_SUCCESS;657658switch (opcode) {659case HCI_CMD_RESET:660RS_INFO("Received cc of hci reset cmd");661rtb_cfg.link_estab_state = H5_ACTIVE;662break;663default:664break;665}666}667668/*669* Process a hci frame670*/671static void hci_recv_frame(struct sk_buff *skb)672{673if (rtb_cfg.link_estab_state == H5_INIT) {674if (skb->data[0] == 0x0e)675h5_init_hci_cc(skb);676677/*678* rtb_send_ack(rtb_cfg.serial_fd);679* usleep(10000);680* rtb_send_ack(rtb_cfg.serial_fd);681*/682} else if (rtb_cfg.link_estab_state == H5_PATCH) {683if (skb->data[0] != 0x0e) {684RS_INFO("Received event 0x%x during download patch",685skb->data[0]);686return;687}688689rtb_cfg.rx_index = skb->data[6];690691/* RS_INFO("rx_index %d", rtb_cfg.rx_index); */692693/* Download fw/config done */694if (rtb_cfg.rx_index & 0x80) {695rtb_cfg.rx_index &= ~0x80;696rtb_cfg.link_estab_state = H5_HCI_RESET;697}698} else if (rtb_cfg.link_estab_state == H5_HCI_RESET) {699if (skb->data[0] == 0x0e)700h5_post_hci_cc(skb);701} else {702RS_ERR("receive packets in active state");703}704}705706static void h5_handle_internal_rx(struct sk_buff *skb)707{708int len;709uint8_t sync_req[2] = { 0x01, 0x7E };710uint8_t sync_resp[2] = { 0x02, 0x7D };711uint8_t sync_resp_pkt[0x8] = {7120xc0, 0x00, 0x2F, 0x00, 0xD0, 0x02, 0x7D, 0xc0713};714uint8_t conf_req[2] = { 0x03, 0xFC };715uint8_t conf_resp[2] = { 0x04, 0x7B };716uint8_t conf_resp_pkt[0x8] = {7170xc0, 0x00, 0x2F, 0x00, 0xD0, 0x04, 0x7B, 0xc0718};719720if (rtb_cfg.link_estab_state == H5_SYNC) {721if (!memcmp(skb->data, sync_req, 2)) {722RS_INFO("[SYNC] Get SYNC Pkt\n");723len = write(rtb_cfg.serial_fd, sync_resp_pkt, 0x8);724if (len != 0x08)725RS_ERR("Send h5 sync resp error, %s",726strerror(errno));727} else if (!memcmp(skb->data, sync_resp, 2)) {728RS_INFO("[SYNC] Get SYNC Resp Pkt");729rtb_cfg.link_estab_state = H5_CONFIG;730}731} else if (rtb_cfg.link_estab_state == H5_CONFIG) {732if (!memcmp(skb->data, sync_req, 0x2)) {733RS_INFO("[CONFIG] Get SYNC pkt");734len = write(rtb_cfg.serial_fd, sync_resp_pkt, 0x8);735if (len != 0x08)736RS_ERR("Send h5 sync resp error, %s",737strerror(errno));738} else if (!memcmp(skb->data, conf_req, 0x2)) {739RS_INFO("[CONFIG] Get CONFG pkt");740len = write(rtb_cfg.serial_fd, conf_resp_pkt, 0x8);741if (len != 0x08)742RS_ERR("Send h5 sync resp to ctl error, %s",743strerror(errno));744} else if (!memcmp(skb->data, conf_resp, 0x2)) {745RS_INFO("[CONFIG] Get CONFG resp pkt");746/* Change state to H5_INIT after receiving a conf resp747*/748rtb_cfg.link_estab_state = H5_INIT;749if (skb->data_len > 2) {750rtb_cfg.use_crc = ((skb->data[2]) >> 4) & 0x01;751RS_INFO("dic is %u, cfg field 0x%02x",752rtb_cfg.use_crc, skb->data[2]);753}754} else {755RS_WARN("[CONFIG] Get unknown pkt");756rtb_send_ack(rtb_cfg.serial_fd);757}758}759}760761/*762* Process the received complete h5 packet763*/764static void h5_complete_rx_pkt(struct rtb_struct *h5)765{766int pass_up = 1;767uint8_t *h5_hdr = NULL;768769h5_hdr = (uint8_t *) (h5->rx_skb->data);770if (H5_HDR_RELIABLE(h5_hdr)) {771/* RS_DBG("Received reliable seqno %u from card", h5->rxseq_txack);772*/773h5->rxseq_txack = H5_HDR_SEQ(h5_hdr) + 1;774/* h5->rxseq_txack %= 8; */775h5->rxseq_txack &= 0x07;776h5->is_txack_req = 1;777}778779h5->rxack = H5_HDR_ACK(h5_hdr);780781switch (H5_HDR_PKT_TYPE(h5_hdr)) {782case HCI_ACLDATA_PKT:783case HCI_EVENT_PKT:784case HCI_COMMAND_PKT:785/* h5_remove_acked_pkt(h5); */786pass_up = 1;787break;788case HCI_SCODATA_PKT:789pass_up = 1;790break;791case H5_LINK_CTL_PKT:792pass_up = 0;793skb_pull(h5->rx_skb, H5_HDR_SIZE);794h5_handle_internal_rx(h5->rx_skb);795break;796default: /* Pure ack or other unexpected pkt */797pass_up = 0;798break;799}800801if (pass_up) {802skb_pull(h5->rx_skb, H5_HDR_SIZE);803hci_recv_frame(h5->rx_skb);804}805806if (h5->is_txack_req) {807rtb_send_ack(rtb_cfg.serial_fd);808h5->is_txack_req = 0;809}810811skb_free(h5->rx_skb);812813h5->rx_state = H5_W4_PKT_DELIMITER;814h5->rx_skb = NULL;815}816817/*818* Parse the receive data in h5 proto.819*/820static int h5_recv(struct rtb_struct *h5, void *data, int count)821{822unsigned char *ptr;823ptr = (unsigned char *)data;824825while (count) {826if (h5->rx_count) {827if (*ptr == 0xc0) {828RS_ERR("Short h5 packet");829skb_free(h5->rx_skb);830h5->rx_state = H5_W4_PKT_START;831h5->rx_count = 0;832} else833h5_unslip_one_byte(h5, *ptr);834835ptr++;836count--;837continue;838}839840switch (h5->rx_state) {841case H5_W4_HDR:842/* Check header checksum */843if ((0xff & (uint8_t)~(h5->rx_skb->data[0] + h5->rx_skb->data[1] +844h5->rx_skb->data[2])) != h5->rx_skb->data[3]) {845RS_ERR("h5 hdr checksum error");846skb_free(h5->rx_skb);847h5->rx_state = H5_W4_PKT_DELIMITER;848h5->rx_count = 0;849continue;850}851852/* The received seq number is unexpected */853if (h5->rx_skb->data[0] & 0x80 &&854(h5->rx_skb->data[0] & 0x07) != h5->rxseq_txack) {855uint8_t rxseq_txack = (h5->rx_skb->data[0] & 0x07);856RS_ERR("Out-of-order packet arrived, got(%u)expected(%u)",857h5->rx_skb->data[0] & 0x07,858h5->rxseq_txack);859h5->is_txack_req = 1;860861skb_free(h5->rx_skb);862h5->rx_state = H5_W4_PKT_DELIMITER;863h5->rx_count = 0;864865/* Depend on whether Controller will reset ack866* number or not867*/868if (rtb_cfg.link_estab_state == H5_PATCH &&869rtb_cfg.tx_index == rtb_cfg.total_num)870rtb_cfg.rxseq_txack = rxseq_txack;871872continue;873}874h5->rx_state = H5_W4_DATA;875h5->rx_count =876(h5->rx_skb->data[1] >> 4) +877(h5->rx_skb->data[2] << 4);878continue;879880case H5_W4_DATA:881/* Packet with crc */882if (h5->rx_skb->data[0] & 0x40) {883h5->rx_state = H5_W4_CRC;884h5->rx_count = 2;885} else {886h5_complete_rx_pkt(h5);887}888continue;889890case H5_W4_CRC:891if (bit_rev16(h5->message_crc) != h5_get_crc(h5)) {892RS_ERR("Checksum failed, computed %04x received %04x",893bit_rev16(h5->message_crc),894h5_get_crc(h5));895skb_free(h5->rx_skb);896h5->rx_state = H5_W4_PKT_DELIMITER;897h5->rx_count = 0;898continue;899}900skb_trim(h5->rx_skb, h5->rx_skb->data_len - 2);901h5_complete_rx_pkt(h5);902continue;903904case H5_W4_PKT_DELIMITER:905switch (*ptr) {906case 0xc0:907h5->rx_state = H5_W4_PKT_START;908break;909910default:911break;912}913ptr++;914count--;915break;916917case H5_W4_PKT_START:918switch (*ptr) {919case 0xc0:920ptr++;921count--;922break;923924default:925h5->rx_state = H5_W4_HDR;926h5->rx_count = 4;927h5->rx_esc_state = H5_ESCSTATE_NOESC;928H5_CRC_INIT(h5->message_crc);929930/* Do not increment ptr or decrement count931* Allocate packet. Max len of a H5 pkt=932* 0xFFF (payload) +4 (header) +2 (crc)933*/934h5->rx_skb = skb_alloc(0x1005);935if (!h5->rx_skb) {936RS_ERR("Can't alloc skb for new pkt");937h5->rx_state = H5_W4_PKT_DELIMITER;938h5->rx_count = 0;939return 0;940}941break;942}943break;944945default:946break;947}948}949return count;950}951952static const char *op_string(uint32_t op)953{954switch (op) {955case OP_SET_BAUD:956return "OP_SET_BAUD";957case OP_H5_SYNC:958return "OP_H5_SYNC";959case OP_H5_CONFIG:960return "OP_H5_CONFIG";961case OP_HCI_RESET:962return "OP_HCI_RESET";963case OP_CHIP_TYPE:964return "OP_CHIP_TYPE";965case OP_ROM_VER:966return "OP_ROM_VER";967case OP_LMP_VER:968return "OP_LMP_VER";969default:970return "OP_UNKNOWN";971}972}973974static int start_transmit_wait(int fd, struct sk_buff *skb,975uint32_t op, unsigned int msec, int retry)976{977unsigned char buf[128];978ssize_t result;979struct iovec iov;980ssize_t ret;981uint8_t *data;982int len;983int op_result = -1;984uint64_t expired;985int n;986struct epoll_event events[MAX_EVENTS];987int nfds;988uint16_t opcode = 0;989990if (fd == -1 || !skb) {991RS_ERR("Invalid parameter");992return -1;993}994995data = skb->data;996len = skb->data_len;997998if (op & (1 << 24)) {999opcode = (op & 0xffff);1000if (opcode != rtb_cfg.cmd_state.opcode ||1001rtb_cfg.cmd_state.state != CMD_STATE_UNKNOWN) {1002RS_ERR("Invalid opcode or cmd state");1003return -1;1004}1005}10061007iov.iov_base = data;1008iov.iov_len = len;1009do {1010ret = writev(fd, &iov, 1);1011if (ret != len)1012RS_WARN("Writev partially, ret %d", (int)ret);1013} while (ret < 0 && errno == EINTR);10141015if (ret < 0) {1016RS_ERR("Call writev error, %s", strerror(errno));1017return -errno;1018}10191020/* Set timeout */1021if (rtb_cfg.timerfd > 0)1022timeout_set(rtb_cfg.timerfd, msec);10231024do {1025nfds = epoll_wait(rtb_cfg.epollfd, events, MAX_EVENTS, msec);1026if (nfds == -1) {1027RS_ERR("epoll_wait, %s (%d)", strerror(errno), errno);1028exit(EXIT_FAILURE);1029}10301031for (n = 0; n < nfds; ++n) {1032if (events[n].data.fd == rtb_cfg.serial_fd) {1033if (events[n].events & (EPOLLERR | EPOLLHUP |1034EPOLLRDHUP)) {1035RS_ERR("%s: Error happens on serial fd",1036__func__);1037exit(EXIT_FAILURE);1038}1039result = read(events[n].data.fd, buf,1040sizeof(buf));1041if (result <= 0) {1042RS_ERR("Read serial error, %s",1043strerror(errno));1044continue;1045} else {1046h5_recv(&rtb_cfg, buf, result);1047}1048} else if (events[n].data.fd == rtb_cfg.timerfd) {1049if (events[n].events & (EPOLLERR | EPOLLHUP |1050EPOLLRDHUP)) {1051RS_ERR("%s: Error happens on timer fd",1052__func__);1053exit(EXIT_FAILURE);1054}1055RS_WARN("%s Transmission timeout",1056op_string(op));1057result = read(events[n].data.fd, &expired,1058sizeof(expired));1059if (result != sizeof(expired)) {1060RS_ERR("Skip retransmit");1061break;1062}1063if (retry <= 0) {1064RS_ERR("Retransmission exhausts");1065tcflush(fd, TCIOFLUSH);1066exit(EXIT_FAILURE);1067}10681069iov.iov_base = data;1070iov.iov_len = len;10711072do {1073ret = writev(fd, &iov, 1);1074if (ret != len)1075RS_WARN("Writev partial, %d",1076(int)ret);1077} while (ret < 0 && errno == EINTR);10781079if (ret < 0) {1080RS_ERR("ReCall writev error, %s",1081strerror(errno));1082return -errno;1083}10841085retry--;1086timeout_set(rtb_cfg.timerfd, msec);1087}1088}10891090if (!(op & (1 << 24))) {1091/* h5 sync or config */1092if (op == OP_H5_SYNC && rtb_cfg.link_estab_state ==1093H5_CONFIG) {1094op_result = 0;1095break;1096}10971098if (op == OP_H5_CONFIG && rtb_cfg.link_estab_state ==1099H5_INIT) {1100op_result = 0;1101break;1102}1103continue;1104}11051106if (rtb_cfg.cmd_state.opcode == opcode &&1107rtb_cfg.cmd_state.state == CMD_STATE_SUCCESS) {1108op_result = 0;1109break;1110}1111} while (1);11121113/* Disarms timer */1114timeout_set(rtb_cfg.timerfd, 0);11151116return op_result;1117}11181119static int h5_download_patch(int dd, int index, uint8_t *data, int len,1120struct termios *ti)1121{1122unsigned char buf[64];1123int retlen;1124struct iovec iov;1125ssize_t ret;1126int nfds;1127struct epoll_event events[MAX_EVENTS];1128int n;1129int timeout;1130uint64_t expired;1131int retry = 3;1132struct sk_buff *nskb;1133uint8_t hci_patch[PATCH_DATA_FIELD_MAX_SIZE + 4];11341135if (index & 0x80) {1136rtb_cfg.tx_index = index & 0x7f;1137timeout = 1000;1138} else {1139rtb_cfg.tx_index = index;1140timeout = 800;1141}11421143/* download cmd: 0xfc20 */1144hci_patch[0] = 0x20;1145hci_patch[1] = 0xfc;1146hci_patch[2] = len + 1;1147hci_patch[3] = (uint8_t)index;1148if (data)1149memcpy(&hci_patch[4], data, len);11501151/* length: 2-byte opcode + 1-byte len + 1-byte index + payload */1152nskb = h5_prepare_pkt(&rtb_cfg, hci_patch, len + 4, HCI_COMMAND_PKT);1153if (!nskb) {1154RS_ERR("Prepare command packet for download");1155return -1;1156}11571158/* Save pkt address and length for re-transmission */1159len = nskb->data_len;1160data = nskb->data;11611162iov.iov_base = nskb->data;1163iov.iov_len = nskb->data_len;1164do {1165ret = writev(dd, &iov, 1);1166if (ret != len)1167RS_WARN("Writev partially, ret %d", (int)ret);1168} while (ret < 0 && errno == EINTR);11691170if (ret < 0) {1171RS_ERR("Call writev error, %s", strerror(errno));1172skb_free(nskb);1173return -errno;1174}11751176/* RS_INFO("%s: tx_index %d, rx_index %d", __func__,1177* rtb_cfg.tx_index, rtb_cfg.rx_index);1178*/11791180if (index & 0x80) {1181/* For the last pkt, wait for its complete */1182tcdrain(dd);11831184if (rtb_cfg.uart_flow_ctrl) {1185RS_INFO("Enable host hw flow control");1186ti->c_cflag |= CRTSCTS;1187} else {1188RS_INFO("Disable host hw flow control");1189ti->c_cflag &= ~CRTSCTS;1190}11911192if (tcsetattr(dd, TCSANOW, ti) < 0) {1193RS_ERR("Can't set port settings");1194skb_free(nskb);1195return -1;1196}11971198/* RS_INFO("Change baud to %d", rtb_cfg.final_speed);1199* if (set_speed(dd, ti, rtb_cfg.final_speed) < 0) {1200* RS_ERR("Set final speed %d error",1201* rtb_cfg.final_speed);1202* }1203*/1204}12051206if (rtb_cfg.timerfd > 0)1207timeout_set(rtb_cfg.timerfd, timeout);12081209do {1210nfds = epoll_wait(rtb_cfg.epollfd, events, MAX_EVENTS, -1);1211if (nfds == -1) {1212RS_ERR("epoll_wait, %s (%d)", strerror(errno), errno);1213exit(EXIT_FAILURE);1214}12151216for (n = 0; n < nfds; ++n) {1217if (events[n].data.fd == dd) {1218if (events[n].events & (EPOLLERR | EPOLLHUP |1219EPOLLRDHUP)) {1220RS_ERR("%s: Error happens on serial fd",1221__func__);1222exit(EXIT_FAILURE);1223}1224retlen = read(dd, buf, sizeof(buf));1225if (retlen <= 0) {1226RS_ERR("Read serial error, %s", strerror(errno));1227continue;1228} else {1229h5_recv(&rtb_cfg, buf, retlen);1230}1231} else if (events[n].data.fd == rtb_cfg.timerfd) {1232int fd = events[n].data.fd;12331234if (events[n].events & (EPOLLERR | EPOLLHUP |1235EPOLLRDHUP)) {1236RS_ERR("%s: Error happens on timer fd",1237__func__);1238exit(EXIT_FAILURE);1239}1240RS_WARN("Patch pkt trans timeout, re-trans");1241ret = read(fd, &expired, sizeof(expired));1242if (ret != sizeof(expired)) {1243RS_ERR("Read expired info error");1244exit(EXIT_FAILURE);1245}1246if (retry <= 0) {1247RS_ERR("%s: Retransmission exhausts",1248__func__);1249tcflush(fd, TCIOFLUSH);1250exit(EXIT_FAILURE);1251}12521253iov.iov_base = data;1254iov.iov_len = len;12551256do {1257ret = writev(dd, &iov, 1);1258if (ret != len)1259RS_WARN("Writev partial, %d",1260(int)ret);1261} while (ret < 0 && errno == EINTR);12621263if (ret < 0) {1264RS_ERR("ReCall writev error, %s",1265strerror(errno));1266skb_free(nskb);1267return -errno;1268}12691270retry--;1271timeout_set(fd, timeout);1272}1273}1274} while (rtb_cfg.rx_index != rtb_cfg.tx_index);12751276/* Disarms timer */1277if (rtb_cfg.timerfd > 0)1278timeout_set(rtb_cfg.timerfd, 0);12791280skb_free(nskb);1281return 0;1282}12831284/*1285* Change the Controller's UART speed.1286*/1287int h5_vendor_change_speed(int fd, uint32_t baudrate)1288{1289struct sk_buff *nskb = NULL;1290unsigned char cmd[16] = { 0 };1291int result;12921293cmd[0] = 0x17;1294cmd[1] = 0xfc;1295cmd[2] = 4;12961297baudrate = cpu_to_le32(baudrate);1298#ifdef BAUDRATE_4BYTES1299memcpy((uint16_t *) & cmd[3], &baudrate, 4);1300#else1301memcpy((uint16_t *) & cmd[3], &baudrate, 2);13021303cmd[5] = 0;1304cmd[6] = 0;1305#endif13061307RS_DBG("baudrate in change speed command: 0x%02x 0x%02x 0x%02x 0x%02x",1308cmd[3], cmd[4], cmd[5], cmd[6]);13091310nskb = h5_prepare_pkt(&rtb_cfg, cmd, 7, HCI_COMMAND_PKT);1311if (!nskb) {1312RS_ERR("Prepare command packet for change speed fail");1313return -1;1314}13151316rtb_cfg.cmd_state.opcode = HCI_VENDOR_CHANGE_BAUD;;1317rtb_cfg.cmd_state.state = CMD_STATE_UNKNOWN;1318result = start_transmit_wait(fd, nskb, OP_SET_BAUD, 1000, 0);1319skb_free(nskb);1320if (result < 0) {1321RS_ERR("OP_SET_BAUD Transmission error");1322return result;1323}13241325return 0;1326}13271328/*1329* Init realtek Bluetooth h5 proto.1330* There are two steps: h5 sync and h5 config.1331*/1332int rtb_init_h5(int fd, struct termios *ti)1333{1334struct sk_buff *nskb;1335unsigned char h5sync[2] = { 0x01, 0x7E };1336/* 16-bit CCITT CRC may be used and the sliding win size is 4 */1337unsigned char h5conf[3] = { 0x03, 0xFC, 0x14 };1338int result;13391340/* Disable CRTSCTS by default */1341ti->c_cflag &= ~CRTSCTS;13421343/* set even parity */1344ti->c_cflag |= PARENB;1345ti->c_cflag &= ~(PARODD);1346if (tcsetattr(fd, TCSANOW, ti) < 0) {1347RS_ERR("Can't set port settings");1348return -1;1349}13501351/* h5 sync */1352rtb_cfg.link_estab_state = H5_SYNC;1353nskb = h5_prepare_pkt(&rtb_cfg, h5sync, sizeof(h5sync),1354H5_LINK_CTL_PKT);1355result = start_transmit_wait(fd, nskb, OP_H5_SYNC, 500, 10);1356skb_free(nskb);1357if (result < 0) {1358RS_ERR("OP_H5_SYNC Transmission error");1359return -1;1360}13611362/* h5 config */1363nskb = h5_prepare_pkt(&rtb_cfg, h5conf, sizeof(h5conf), H5_LINK_CTL_PKT);1364result = start_transmit_wait(fd, nskb, OP_H5_CONFIG, 500, 10);1365skb_free(nskb);1366if (result < 0) {1367RS_ERR("OP_H5_CONFIG Transmission error");1368return -1;1369}13701371rtb_send_ack(fd);1372RS_DBG("H5 init finished\n");13731374rtb_cfg.cmd_state.state = CMD_STATE_UNKNOWN;13751376return 0;1377}13781379static int h5_hci_reset(int fd)1380{1381uint8_t cmd[3] = { 0x03, 0x0c, 0x00};1382struct sk_buff *nskb;1383int result;13841385RS_INFO("%s: Issue hci reset cmd", __func__);13861387nskb = h5_prepare_pkt(&rtb_cfg, cmd, sizeof(cmd), HCI_COMMAND_PKT);1388if (!nskb) {1389RS_ERR("%s: Failed to alloc mem for hci reset skb", __func__);1390return -1;1391}13921393rtb_cfg.cmd_state.opcode = HCI_CMD_RESET;1394rtb_cfg.cmd_state.state = CMD_STATE_UNKNOWN;13951396result = start_transmit_wait(fd, nskb, OP_HCI_RESET, 1500, 1);1397skb_free(nskb);1398if (result < 0)1399RS_ERR("hci reset failed");14001401return result;1402}14031404#ifdef SERIAL_NONBLOCK_READ1405static int set_fd_nonblock(int fd)1406{1407long arg;1408int old_fl;14091410arg = fcntl(fd, F_GETFL);1411if (arg < 0)1412return -errno;14131414/* Return if already nonblock */1415if (arg & O_NONBLOCK)1416return FD_NONBLOCK;1417old_fl = FD_BLOCK;14181419arg |= O_NONBLOCK;1420if (fcntl(fd, F_SETFL, arg) < 0)1421return -errno;14221423return old_fl;1424}14251426static int set_fd_block(int fd)1427{1428long arg;14291430arg = fcntl(fd, F_GETFL);1431if (arg < 0)1432return -errno;14331434/* Return if already block */1435if (!(arg & O_NONBLOCK))1436return 0;14371438arg &= ~O_NONBLOCK;1439if (fcntl(fd, F_SETFL, arg) < 0)1440return -errno;14411442return 0;1443}1444#endif14451446/*1447* Download Realtek Firmware and Config1448*/1449static int rtb_download_fwc(int fd, uint8_t *buf, int size, int proto,1450struct termios *ti)1451{1452uint8_t curr_idx = 0;1453uint8_t curr_len = 0;1454uint8_t lp_len = 0;1455uint8_t add_pkts = 0;1456uint16_t end_idx = 0;1457uint16_t total_idx = 0;1458uint16_t num;1459unsigned char *pkt_buf;1460uint16_t i, j;1461int result;1462#ifdef SERIAL_NONBLOCK_READ1463int old_fl;1464#endif14651466end_idx = (uint16_t)((size - 1) / PATCH_DATA_FIELD_MAX_SIZE);1467lp_len = size % PATCH_DATA_FIELD_MAX_SIZE;14681469num = rtb_cfg.num_of_cmd_sent;1470num += end_idx + 1;14711472add_pkts = num % 8 ? (8 - num % 8) : 0;14731474#ifdef SERIAL_NONBLOCK_READ1475old_fl = set_fd_nonblock(fd);1476if (old_fl < 0) {1477RS_ERR("Set fd nonblock error, %s", strerror(errno));1478}1479if (old_fl == FD_BLOCK)1480RS_INFO("old fd state is block");1481#endif14821483/* Make sure the next seqno is zero after download patch and1484* hci reset1485*/1486if (proto == HCI_UART_3WIRE) {1487if (add_pkts)1488add_pkts -= 1;1489else1490add_pkts += 7;1491} else1492add_pkts = 0; /* No additional packets need */14931494total_idx = add_pkts + end_idx;1495rtb_cfg.total_num = total_idx;14961497RS_INFO("end_idx: %u, lp_len: %u, additional pkts: %u\n", end_idx,1498lp_len, add_pkts);1499RS_INFO("Start downloading...");15001501if (lp_len == 0)1502lp_len = PATCH_DATA_FIELD_MAX_SIZE;15031504pkt_buf = buf;15051506for (i = 0; i <= total_idx; i++) {1507/* Index will roll over when it reaches 0x801508* 0, 1, 2, 3, ..., 126, 127(7f), 1, 2, 3, ...1509*/1510if (i > 0x7f)1511j = (i & 0x7f) + 1;1512else1513j = i;15141515if (i < end_idx) {1516curr_idx = j;1517curr_len = PATCH_DATA_FIELD_MAX_SIZE;1518} else if (i == end_idx) {1519/* Send last data packets */1520if (i == total_idx)1521curr_idx = j | 0x80;1522else1523curr_idx = j;1524curr_len = lp_len;1525} else if (i < total_idx) {1526/* Send additional packets */1527curr_idx = j;1528pkt_buf = NULL;1529curr_len = 0;1530RS_INFO("Send additional packet %u", curr_idx);1531} else {1532/* Send last packet */1533curr_idx = j | 0x80;1534pkt_buf = NULL;1535curr_len = 0;1536RS_INFO("Last packet %u", curr_idx);1537}15381539if (curr_idx & 0x80)1540RS_INFO("Send last pkt");15411542if (proto == HCI_UART_H4) {1543curr_idx = h4_download_patch(fd, curr_idx, pkt_buf,1544curr_len);1545if (curr_idx != j && i != total_idx) {1546RS_ERR("Index mismatch %u, curr_idx %u", j,1547curr_idx);1548return -1;1549}1550} else if (proto == HCI_UART_3WIRE) {1551if (h5_download_patch(fd, curr_idx, pkt_buf, curr_len,1552ti) < 0)1553return -1;1554}15551556if (curr_idx < end_idx) {1557pkt_buf += PATCH_DATA_FIELD_MAX_SIZE;1558}1559}15601561/* Make hci reset after Controller applies the Firmware and Config */1562if (proto == HCI_UART_H4)1563result = h4_hci_reset(fd);1564else1565result = h5_hci_reset(fd);15661567if (proto == HCI_UART_3WIRE) {1568/* Make sure the last pure ack is sent */1569tcdrain(fd);1570}15711572if (result)1573return result;157415751576#ifdef SERIAL_NONBLOCK_READ1577if (old_fl == FD_BLOCK)1578set_fd_block(fd);1579#endif15801581return 0;1582}15831584#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]) )1585struct rtb_baud {1586uint32_t rtb_speed;1587int uart_speed;1588};15891590#ifdef BAUDRATE_4BYTES1591struct rtb_baud baudrates[] = {1592#ifdef RTL_8703A_SUPPORT1593{0x00004003, 1500000}, /* for rtl8703as */1594#endif1595{0x0252C014, 115200},1596{0x0252C00A, 230400},1597{0x05F75004, 921600},1598{0x00005004, 1000000},1599{0x04928002, 1500000},1600{0x01128002, 1500000}, //8761AT1601{0x00005002, 2000000},1602{0x0000B001, 2500000},1603{0x04928001, 3000000},1604{0x052A6001, 3500000},1605{0x00005001, 4000000},1606};1607#else1608struct rtb_baud baudrates[] = {1609{0x701d, 115200}1610{0x6004, 921600},1611{0x4003, 1500000},1612{0x5002, 2000000},1613{0x8001, 3000000},1614{0x9001, 3000000},1615{0x7001, 3500000},1616{0x5001, 4000000},1617};1618#endif16191620static void vendor_speed_to_std(uint32_t rtb_speed, uint32_t *uart_speed)1621{1622*uart_speed = 115200;16231624unsigned int i;1625for (i = 0; i < ARRAY_SIZE(baudrates); i++) {1626if (baudrates[i].rtb_speed == rtb_speed) {1627*uart_speed = baudrates[i].uart_speed;1628return;1629}1630}1631return;1632}16331634static inline void std_speed_to_vendor(int uart_speed, uint32_t *rtb_speed)1635{1636*rtb_speed = 0x701D;16371638unsigned int i;1639for (i = 0; i < ARRAY_SIZE(baudrates); i++) {1640if (baudrates[i].uart_speed == uart_speed) {1641*rtb_speed = baudrates[i].rtb_speed;1642return;1643}1644}16451646return;1647}16481649void rtb_read_chip_type(int dd)1650{1651/* 0xB000A094 */1652unsigned char cmd_buff[] = {16530x61, 0xfc, 0x05, 0x00, 0x94, 0xa0, 0x00, 0xb01654};1655struct sk_buff *nskb;1656int result;16571658nskb = h5_prepare_pkt(&rtb_cfg, cmd_buff, sizeof(cmd_buff),1659HCI_COMMAND_PKT);1660if (!nskb) {1661RS_ERR("Alloc chip type cmd skb buff error");1662exit(EXIT_FAILURE);1663}16641665rtb_cfg.cmd_state.opcode = HCI_VENDOR_READ_CHIP_TYPE;1666rtb_cfg.cmd_state.state = CMD_STATE_UNKNOWN;1667result = start_transmit_wait(dd, nskb, OP_CHIP_TYPE, 250, 3);1668skb_free(nskb);1669if (result < 0)1670RS_ERR("OP_CHIP_TYPE Transmission error");16711672return;1673}16741675/*1676* Read ECO version with vendor cmd 0xfc651677*/1678void rtb_read_eversion(int dd)1679{1680int result;1681unsigned char cmd_buf[3] = { 0x6d, 0xfc, 0x00 };1682struct sk_buff *nskb;16831684nskb= h5_prepare_pkt(&rtb_cfg, cmd_buf, 3, HCI_COMMAND_PKT);1685if (!nskb) {1686RS_ERR("Alloc eversion cmd skb buff error");1687exit(EXIT_FAILURE);1688}16891690rtb_cfg.cmd_state.opcode = HCI_VENDOR_READ_ROM_VER;1691rtb_cfg.cmd_state.state = CMD_STATE_UNKNOWN;1692result = start_transmit_wait(dd, nskb, OP_ROM_VER, 500, 3);1693skb_free(nskb);1694if (result < 0) {1695RS_ERR("OP_ROM_VER Transmit error");1696}16971698return;1699}17001701void rtb_read_local_version(int dd)1702{1703int result;1704unsigned char cmd_buf[3] = { 0x01, 0x10, 0x00 };1705struct sk_buff *nskb;17061707nskb = h5_prepare_pkt(&rtb_cfg, cmd_buf, 3, HCI_COMMAND_PKT);1708if (!nskb) {1709RS_ERR("Alloc local ver cmd skb buff error");1710exit(EXIT_FAILURE);1711}17121713rtb_cfg.cmd_state.state = CMD_STATE_UNKNOWN;1714rtb_cfg.cmd_state.opcode = HCI_CMD_READ_LOCAL_VER;1715result = start_transmit_wait(dd, nskb, OP_LMP_VER, 500, 3);1716skb_free(nskb);1717if (result < 0) {1718RS_ERR("OP_LMP_VER Transmit error");1719}17201721return;1722}17231724/*1725* Config Realtek Bluetooth.1726* Config parameters are got from Realtek Config file and FW.1727*1728* speed is the init_speed in uart struct1729* Returns 0 on success1730*/1731static int rtb_config(int fd, int proto, int speed, struct termios *ti)1732{1733int final_speed = 0;1734int ret = 0;17351736rtb_cfg.proto = proto;17371738/* Read Local Version Information and RTK ROM version */1739if (proto == HCI_UART_3WIRE) {1740RS_INFO("Realtek H5 IC");1741rtb_read_local_version(fd);1742rtb_read_eversion(fd);1743} else {1744RS_INFO("Realtek H4 IC");17451746/* The following set is for special requirement that enables1747* flow control before initializing */1748#ifdef RTL8723DSH4_UART_HWFLOWC1749ti->c_cflag &= ~PARENB;1750ti->c_cflag |= CRTSCTS;1751if (tcsetattr(fd, TCSANOW, ti) < 0) {1752RS_ERR("H4 Can't enable RTSCTS");1753return -1;1754}1755usleep(20 * 1000);1756#endif1757h4_read_local_ver(fd);1758h4_vendor_read_rom_ver(fd);1759if (rtb_cfg.lmp_subver == ROM_LMP_8761btc) {1760/* 8761B Test Chip */1761rtb_cfg.chip_type = CHIP_8761BTC;1762rtb_cfg.uart_flow_ctrl = 1;1763/* TODO: Change to different uart baud */1764std_speed_to_vendor(1500000, &rtb_cfg.vendor_baud);1765goto change_baud;1766} else if (rtb_cfg.lmp_subver == ROM_LMP_8761a) {1767if (rtb_cfg.hci_rev == 0x000b) {1768/* 8761B Test Chip without download */1769rtb_cfg.chip_type = CHIP_8761BH4;1770/* rtb_cfg.uart_flow_ctrl = 1; */1771/* TODO: Change to different uart baud */1772/* std_speed_to_vendor(1500000, &rtb_cfg.vendor_baud);1773* goto change_baud;1774*/1775} else if (rtb_cfg.hci_rev == 0x000a) {1776if (rtb_cfg.eversion == 3)1777rtb_cfg.chip_type = CHIP_8761ATF;1778else if (rtb_cfg.eversion == 2)1779rtb_cfg.chip_type = CHIP_8761AT;1780else1781rtb_cfg.chip_type = CHIP_UNKNOWN;1782}1783} else if (rtb_cfg.lmp_subver == ROM_LMP_8723b) {1784if (rtb_cfg.hci_ver == 0x08 &&1785rtb_cfg.hci_rev == 0x000d) {1786rtb_cfg.chip_type = CHIP_8723DS;1787} else if (rtb_cfg.hci_ver == 0x06 &&1788rtb_cfg.hci_rev == 0x000b) {1789rtb_cfg.chip_type = CHIP_8723BS;1790} else {1791RS_ERR("H4: unknown chip");1792return -1;1793}1794}17951796}17971798RS_INFO("LMP Subversion 0x%04x", rtb_cfg.lmp_subver);1799RS_INFO("EVersion %u", rtb_cfg.eversion);18001801switch (rtb_cfg.lmp_subver) {1802case ROM_LMP_8723a:1803break;1804case ROM_LMP_8723b:1805#ifdef RTL_8703A_SUPPORT1806/* Set chip type for matching fw/config entry */1807rtl->chip_type = CHIP_8703AS;1808#endif1809break;1810case ROM_LMP_8821a:1811break;1812case ROM_LMP_8761a:1813break;1814case ROM_LMP_8703b:1815rtb_read_chip_type(fd);1816break;1817}18181819rtb_cfg.patch_ent = get_patch_entry(&rtb_cfg);1820if (rtb_cfg.patch_ent) {1821RS_INFO("IC: %s", rtb_cfg.patch_ent->ic_name);1822RS_INFO("Firmware/config: %s, %s",1823rtb_cfg.patch_ent->patch_file,1824rtb_cfg.patch_ent->config_file);1825} else {1826RS_ERR("Can not find firmware/config entry\n");1827return -1;1828}18291830rtb_cfg.config_buf = rtb_read_config(&rtb_cfg, &rtb_cfg.config_len);1831if (!rtb_cfg.config_buf) {1832RS_ERR("Read Config file error, use eFuse settings");1833rtb_cfg.config_len = 0;1834}18351836rtb_cfg.fw_buf = rtb_read_firmware(&rtb_cfg, &rtb_cfg.fw_len);1837if (!rtb_cfg.fw_buf) {1838RS_ERR("Read Bluetooth firmware error");1839rtb_cfg.fw_len = 0;1840/* Free config buf */1841if (rtb_cfg.config_buf) {1842free(rtb_cfg.config_buf);1843rtb_cfg.config_buf = NULL;1844rtb_cfg.config_len = 0;1845}1846return -1;1847} else {1848rtb_cfg.total_buf = rtb_get_final_patch(fd, proto,1849&rtb_cfg.total_len);1850/* If the above function executes successfully, the Config and1851* patch were copied to the total buf */18521853/* Free config buf */1854if (rtb_cfg.config_buf) {1855free(rtb_cfg.config_buf);1856rtb_cfg.config_buf = NULL;1857}1858/* Free the fw buf */1859free(rtb_cfg.fw_buf);1860rtb_cfg.fw_buf = NULL;1861rtb_cfg.fw_len = 0;18621863if (!rtb_cfg.total_buf) {1864RS_ERR("Failed to get the final patch");1865exit(EXIT_FAILURE);1866}1867}18681869if (rtb_cfg.total_len > RTB_PATCH_LENGTH_MAX) {1870RS_ERR("Total length of fwc is larger than allowed");1871goto buf_free;1872}18731874RS_INFO("Total len %d for fwc", rtb_cfg.total_len);18751876/* rtl8723ds h4 */1877if (rtb_cfg.chip_type == CHIP_8723DS &&1878rtb_cfg.proto == HCI_UART_H4) {1879if (rtb_cfg.parenb) {1880/* set parity */1881ti->c_cflag |= PARENB;1882if (rtb_cfg.pareven)1883ti->c_cflag &= ~(PARODD);1884else1885ti->c_cflag |= PARODD;1886if (tcsetattr(fd, TCSANOW, ti) < 0) {1887RS_ERR("8723DSH4 Can't set parity");1888goto buf_free;1889}1890}1891}18921893change_baud:1894/* change baudrate if needed1895* rtb_cfg.vendor_baud is a __u32/__u16 vendor-specific variable1896* parsed from config file1897* */1898if (rtb_cfg.vendor_baud == 0) {1899/* No baud setting in Config file */1900std_speed_to_vendor(speed, &rtb_cfg.vendor_baud);1901RS_INFO("No baud from Config file, set baudrate: %d, 0x%08x",1902speed, rtb_cfg.vendor_baud);1903goto start_download;1904} else1905vendor_speed_to_std(rtb_cfg.vendor_baud,1906(uint32_t *)&(rtb_cfg.final_speed));19071908if (rtb_cfg.final_speed == 115200) {1909RS_INFO("Final speed is %d, no baud change needs",1910rtb_cfg.final_speed);1911goto start_download;1912}19131914if (proto == HCI_UART_3WIRE)1915h5_vendor_change_speed(fd, rtb_cfg.vendor_baud);1916else1917h4_vendor_change_speed(fd, rtb_cfg.vendor_baud);19181919/* Make sure the ack for cmd complete event is transmitted */1920tcdrain(fd);1921usleep(50000); /* The same value as before */1922final_speed = rtb_cfg.final_speed ? rtb_cfg.final_speed : speed;1923RS_INFO("Final speed %d", final_speed);1924if (set_speed(fd, ti, final_speed) < 0) {1925RS_ERR("Can't set baud rate: %d, %d, %d", final_speed,1926rtb_cfg.final_speed, speed);1927goto buf_free;1928}19291930start_download:1931/* For 8761B Test chip, no patch to download */1932if (rtb_cfg.chip_type == CHIP_8761BTC)1933goto done;19341935if (rtb_cfg.total_len > 0 && rtb_cfg.dl_fw_flag) {1936rtb_cfg.link_estab_state = H5_PATCH;1937rtb_cfg.rx_index = -1;19381939ret = rtb_download_fwc(fd, rtb_cfg.total_buf, rtb_cfg.total_len,1940proto, ti);1941free(rtb_cfg.total_buf);1942if (ret < 0)1943return ret;1944}19451946done:19471948RS_DBG("Init Process finished");1949return 0;19501951buf_free:1952free(rtb_cfg.total_buf);1953return -1;1954}19551956int rtb_init(int fd, int proto, int speed, struct termios *ti)1957{1958struct epoll_event ev;1959int result;19601961RS_INFO("Realtek hciattach version %s \n", RTK_VERSION);19621963memset(&rtb_cfg, 0, sizeof(rtb_cfg));1964rtb_cfg.serial_fd = fd;1965rtb_cfg.dl_fw_flag = 1;19661967rtb_cfg.epollfd = epoll_create(64);1968if (rtb_cfg.epollfd == -1) {1969RS_ERR("epoll_create1, %s (%d)", strerror(errno), errno);1970exit(EXIT_FAILURE);1971}19721973ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLRDHUP;1974ev.data.fd = fd;1975if (epoll_ctl(rtb_cfg.epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {1976RS_ERR("epoll_ctl: epoll ctl add, %s (%d)", strerror(errno),1977errno);1978exit(EXIT_FAILURE);1979}19801981rtb_cfg.timerfd = timerfd_create(CLOCK_MONOTONIC, 0);1982if (rtb_cfg.timerfd == -1) {1983RS_ERR("timerfd_create error, %s (%d)", strerror(errno), errno);1984return -1;1985}19861987if (rtb_cfg.timerfd > 0) {1988ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLRDHUP;1989ev.data.fd = rtb_cfg.timerfd;1990if (epoll_ctl(rtb_cfg.epollfd, EPOLL_CTL_ADD,1991rtb_cfg.timerfd, &ev) == -1) {1992RS_ERR("epoll_ctl: epoll ctl add, %s (%d)",1993strerror(errno), errno);1994exit(EXIT_FAILURE);1995}1996}19971998RS_INFO("Use epoll");19992000if (proto == HCI_UART_3WIRE) {2001if (rtb_init_h5(fd, ti) < 0)2002return -1;;2003}20042005result = rtb_config(fd, proto, speed, ti);20062007epoll_ctl(rtb_cfg.epollfd, EPOLL_CTL_DEL, fd, NULL);2008epoll_ctl(rtb_cfg.epollfd, EPOLL_CTL_DEL, rtb_cfg.timerfd, NULL);2009close(rtb_cfg.timerfd);2010rtb_cfg.timerfd = -1;20112012return result;2013}20142015int rtb_post(int fd, int proto, struct termios *ti)2016{2017/* No need to change baudrate */2018/* if (rtb_cfg.final_speed)2019* return set_speed(fd, ti, rtb_cfg.final_speed);2020*/20212022return 0;2023}202420252026