1 /******************************************************************************
2 *
3 * Copyright (C) 2009-2018 Realtek Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * Filename: hardware.c
22 *
23 * Description: Contains controller-specific functions, like
24 * firmware patch download
25 * low power mode operations
26 *
27 ******************************************************************************/
28
29 #define LOG_TAG "bt_hwcfg"
30 #define RTKBT_RELEASE_NAME "20190717_BT_ANDROID_9.0"
31
32 #include "hardware.h"
33
34 #include <byteswap.h>
35 #include <ctype.h>
36 #include <dirent.h>
37 #include <endian.h>
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <signal.h>
41 #include <stdlib.h>
42 #include <sys/stat.h>
43 #include <sys/types.h>
44 #include <time.h>
45 #include <unistd.h>
46 #include <utils/Log.h>
47
48 #include "bt_hci_bdroid.h"
49 #include "bt_vendor_lib.h"
50 #include "bt_vendor_rtk.h"
51 #include "upio.h"
52 #include "userial.h"
53 #include "userial_vendor.h"
54
55 /******************************************************************************
56 ** Constants & Macros
57 ******************************************************************************/
58
59 /******************************************************************************
60 ** Externs
61 ******************************************************************************/
62
63 /******************************************************************************
64 ** Static variables
65 ******************************************************************************/
66 bt_hw_cfg_cb_t hw_cfg_cb;
67
getmacaddr(unsigned char * addr)68 int getmacaddr(unsigned char *addr)
69 {
70 int i = 0;
71 char data[256], *str;
72 int addr_fd;
73 uint8_t *p_vnd_local_bd_addr = get_vnd_local_bd_addr();
74
75 char property[100] = {0};
76 (void)memset_s(property, sizeof(property), 0, sizeof(property));
77 (void)strcpy_s(property, sizeof(property), "none");
78 if (strncmp(property, "none", 4L) == 0) {
79 if (strcmp(property, "none") == 0) {
80 return -1;
81 } else if (strcmp(property, "default") == 0) {
82 (void)memcpy_s(addr, BD_ADDR_LEN, p_vnd_local_bd_addr, BD_ADDR_LEN);
83 return 0;
84 } else if ((addr_fd = open(property, O_RDONLY)) != -1) {
85 (void)memset_s(data, sizeof(data), 0, sizeof(data));
86 int ret = read(addr_fd, data, 17L);
87 if (ret < 17L) {
88 HILOGE("%s, read length = %d", __func__, ret);
89 close(addr_fd);
90 return -1;
91 }
92 for (i = 0, str = data; i < 6L; i++) {
93 addr[5L - i] = (unsigned char)strtoul(str, &str, 16L);
94 str++;
95 }
96 close(addr_fd);
97 return 0;
98 }
99 }
100 return -1;
101 }
102
rtk_get_bt_firmware(uint8_t ** fw_buf,char * fw_short_name)103 int rtk_get_bt_firmware(uint8_t **fw_buf, char *fw_short_name)
104 {
105 char filename[PATH_MAX] = {0};
106 struct stat st;
107 int fd = -1;
108 size_t fwsize = 0;
109 size_t buf_size = 0;
110
111 (void)sprintf_s(filename, sizeof(filename), FIRMWARE_DIRECTORY, fw_short_name);
112 HILOGI("BT fw file: %s", filename);
113
114 if (stat(filename, &st) < 0) {
115 HILOGE("Can't access firmware, errno:%d", errno);
116 return -1;
117 }
118
119 fwsize = st.st_size;
120 buf_size = fwsize;
121
122 if ((fd = open(filename, O_RDONLY)) < 0) {
123 HILOGE("Can't open firmware, errno:%d", errno);
124 return -1;
125 }
126
127 if (!(*fw_buf = malloc(buf_size))) {
128 HILOGE("Can't alloc memory for fw&config, errno:%d", errno);
129 if (fd >= 0) {
130 close(fd);
131 }
132 return -1;
133 }
134
135 if (read(fd, *fw_buf, fwsize) < (ssize_t)fwsize) {
136 free(*fw_buf);
137 *fw_buf = NULL;
138 if (fd >= 0) {
139 close(fd);
140 }
141 return -1;
142 }
143
144 if (fd >= 0) {
145 close(fd);
146 }
147
148 HILOGI("Load FW OK");
149 return buf_size;
150 }
151
rtk_get_fw_project_id(uint8_t * p_buf)152 uint8_t rtk_get_fw_project_id(uint8_t *p_buf)
153 {
154 uint8_t opcode;
155 uint8_t len;
156 uint8_t data = 0;
157
158 do {
159 opcode = *p_buf;
160 len = *(p_buf - 1);
161 if (opcode == 0x00) {
162 if (len == 1) {
163 data = *(p_buf - 2L);
164 HILOGI("bt_hw_parse_project_id: opcode %d, len %d, data %d", opcode, len, data);
165 break;
166 } else {
167 HILOGW("bt_hw_parse_project_id: invalid len %d", len);
168 }
169 }
170 p_buf -= len + 2L;
171 } while (*p_buf != 0xFF);
172
173 return data;
174 }
175
get_heartbeat_from_hardware(void)176 uint8_t get_heartbeat_from_hardware(void)
177 {
178 return hw_cfg_cb.heartbeat;
179 }
180
rtk_get_patch_entry(bt_hw_cfg_cb_t * cfg_cb)181 struct rtk_epatch_entry *rtk_get_patch_entry(bt_hw_cfg_cb_t *cfg_cb)
182 {
183 uint16_t i;
184 struct rtk_epatch *patch;
185 struct rtk_epatch_entry *entry;
186 uint8_t *p;
187 uint16_t chip_id;
188
189 patch = (struct rtk_epatch *)cfg_cb->fw_buf;
190 entry = (struct rtk_epatch_entry *)malloc(sizeof(*entry));
191 if (!entry) {
192 HILOGE("rtk_get_patch_entry: failed to allocate mem for patch entry");
193 return NULL;
194 }
195
196 patch->number_of_patch = le16_to_cpu(patch->number_of_patch);
197
198 HILOGI("rtk_get_patch_entry: fw_ver 0x%08x, patch_num %d", le32_to_cpu(patch->fw_version), patch->number_of_patch);
199
200 for (i = 0; i < patch->number_of_patch; i++) {
201 p = cfg_cb->fw_buf + 14L + 2L * i;
202 STREAM_TO_UINT16(chip_id, p);
203 if (chip_id == cfg_cb->eversion + 1) {
204 entry->chip_id = chip_id;
205 p = cfg_cb->fw_buf + 14L + 2L * patch->number_of_patch + 2L * i;
206 STREAM_TO_UINT16(entry->patch_length, p);
207 p = cfg_cb->fw_buf + 14L + 4L * patch->number_of_patch + 4L * i;
208 STREAM_TO_UINT32(entry->patch_offset, p);
209 HILOGI("rtk_get_patch_entry: chip_id %d, patch_len 0x%x, patch_offset 0x%x", entry->chip_id,
210 entry->patch_length, entry->patch_offset);
211 break;
212 }
213 }
214
215 if (i == patch->number_of_patch) {
216 HILOGE("rtk_get_patch_entry: failed to get etnry");
217 free(entry);
218 entry = NULL;
219 }
220
221 return entry;
222 }
223
224 /******************************************************************************
225 ** LPM Static Functions
226 ******************************************************************************/
227
228 /*******************************************************************************
229 **
230 ** Function hw_lpm_ctrl_cback
231 **
232 ** Description Callback function for lpm enable/disable request
233 **
234 ** Returns None
235 **
236 *******************************************************************************/
hw_lpm_ctrl_cback(HC_BT_HDR * p_mem)237 void hw_lpm_ctrl_cback(HC_BT_HDR *p_mem)
238 {
239 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
240
241 if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_OFFSET) == 0) {
242 }
243
244 if (bt_vendor_cbacks) {
245 }
246 }
247
248 #if (HW_END_WITH_HCI_RESET == TRUE)
249 /******************************************************************************
250 *
251 **
252 ** Function hw_epilog_cback
253 **
254 ** Description Callback function for Command Complete Events from HCI
255 ** commands sent in epilog process.
256 **
257 ** Returns None
258 **
259 *******************************************************************************/
hw_epilog_cback(HC_BT_HDR * p_mem)260 void hw_epilog_cback(HC_BT_HDR *p_mem)
261 {
262 HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
263 uint8_t *p, status;
264 uint16_t opcode;
265
266 status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_OFFSET);
267 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE_OFFSET;
268 STREAM_TO_UINT16(opcode, p);
269
270 BTVNDDBG("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status);
271
272 if (bt_vendor_cbacks) {
273 /* Must free the RX event buffer */
274 bt_vendor_cbacks->dealloc(p_evt_buf);
275
276 /* Once epilog process is done, must call epilog_cb callback
277 to notify caller */
278 bt_vendor_cbacks->init_cb(BTC_OP_RESULT_SUCCESS);
279 }
280 }
281
282 /******************************************************************************
283 *
284 **
285 ** Function hw_epilog_process
286 **
287 ** Description Sample implementation of epilog process
288 **
289 ** Returns None
290 **
291 *******************************************************************************/
hw_epilog_process(void)292 void hw_epilog_process(void)
293 {
294 HC_BT_HDR *p_buf = NULL;
295 uint8_t *p;
296
297 BTVNDDBG("hw_epilog_process");
298
299 /* Sending a HCI_RESET */
300 if (bt_vendor_cbacks) {
301 /* Must allocate command buffer via HC's alloc API */
302 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE);
303 }
304
305 if (p_buf) {
306 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
307 p_buf->offset = 0;
308 p_buf->layer_specific = 0;
309 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
310
311 p = (uint8_t *)(p_buf + 1);
312 UINT16_TO_STREAM(p, HCI_RESET);
313 *p = 0; /* parameter length */
314
315 /* Send command via HC's xmit_cb API */
316 bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf);
317 } else {
318 if (bt_vendor_cbacks) {
319 HILOGE("vendor lib epilog process aborted [no buffer]");
320 bt_vendor_cbacks->init_cb(BTC_OP_RESULT_FAIL);
321 }
322 }
323 }
324 #endif // (HW_END_WITH_HCI_RESET == TRUE)
325