]>
Commit | Line | Data |
---|---|---|
83e81961 BYTK |
1 | /* |
2 | * Bluetooth supports for Qualcomm Atheros chips | |
3 | * | |
4 | * Copyright (c) 2015 The Linux Foundation. All rights reserved. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 | |
8 | * as published by the Free Software Foundation | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program; if not, write to the Free Software | |
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | * | |
19 | */ | |
20 | #include <linux/module.h> | |
21 | #include <linux/firmware.h> | |
22 | ||
23 | #include <net/bluetooth/bluetooth.h> | |
24 | #include <net/bluetooth/hci_core.h> | |
25 | ||
26 | #include "btqca.h" | |
27 | ||
28 | #define VERSION "0.1" | |
29 | ||
ba493d4f | 30 | int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version) |
83e81961 BYTK |
31 | { |
32 | struct sk_buff *skb; | |
33 | struct edl_event_hdr *edl; | |
34 | struct rome_version *ver; | |
35 | char cmd; | |
36 | int err = 0; | |
37 | ||
ba493d4f | 38 | bt_dev_dbg(hdev, "QCA Version Request"); |
83e81961 BYTK |
39 | |
40 | cmd = EDL_PATCH_VER_REQ_CMD; | |
41 | skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN, | |
42 | &cmd, HCI_VENDOR_PKT, HCI_INIT_TIMEOUT); | |
43 | if (IS_ERR(skb)) { | |
44 | err = PTR_ERR(skb); | |
ba493d4f BG |
45 | bt_dev_err(hdev, "Reading QCA version information failed (%d)", |
46 | err); | |
83e81961 BYTK |
47 | return err; |
48 | } | |
49 | ||
50 | if (skb->len != sizeof(*edl) + sizeof(*ver)) { | |
ba493d4f | 51 | bt_dev_err(hdev, "QCA Version size mismatch len %d", skb->len); |
83e81961 BYTK |
52 | err = -EILSEQ; |
53 | goto out; | |
54 | } | |
55 | ||
56 | edl = (struct edl_event_hdr *)(skb->data); | |
0676cab4 | 57 | if (!edl) { |
ba493d4f | 58 | bt_dev_err(hdev, "QCA TLV with no header"); |
83e81961 BYTK |
59 | err = -EILSEQ; |
60 | goto out; | |
61 | } | |
62 | ||
63 | if (edl->cresp != EDL_CMD_REQ_RES_EVT || | |
64 | edl->rtype != EDL_APP_VER_RES_EVT) { | |
ba493d4f BG |
65 | bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp, |
66 | edl->rtype); | |
83e81961 BYTK |
67 | err = -EIO; |
68 | goto out; | |
69 | } | |
70 | ||
71 | ver = (struct rome_version *)(edl->data); | |
72 | ||
73 | BT_DBG("%s: Product:0x%08x", hdev->name, le32_to_cpu(ver->product_id)); | |
74 | BT_DBG("%s: Patch :0x%08x", hdev->name, le16_to_cpu(ver->patch_ver)); | |
75 | BT_DBG("%s: ROM :0x%08x", hdev->name, le16_to_cpu(ver->rome_ver)); | |
76 | BT_DBG("%s: SOC :0x%08x", hdev->name, le32_to_cpu(ver->soc_id)); | |
77 | ||
ba493d4f | 78 | /* QCA chipset version can be decided by patch and SoC |
83e81961 BYTK |
79 | * version, combination with upper 2 bytes from SoC |
80 | * and lower 2 bytes from patch will be used. | |
81 | */ | |
ba493d4f | 82 | *soc_version = (le32_to_cpu(ver->soc_id) << 16) | |
2193a980 | 83 | (le16_to_cpu(ver->rome_ver) & 0x0000ffff); |
aadebac4 BG |
84 | if (*soc_version == 0) |
85 | err = -EILSEQ; | |
83e81961 BYTK |
86 | |
87 | out: | |
88 | kfree_skb(skb); | |
aadebac4 BG |
89 | if (err) |
90 | bt_dev_err(hdev, "QCA Failed to get version (%d)", err); | |
83e81961 BYTK |
91 | |
92 | return err; | |
93 | } | |
ba493d4f | 94 | EXPORT_SYMBOL_GPL(qca_read_soc_version); |
83e81961 | 95 | |
ba493d4f | 96 | static int qca_send_reset(struct hci_dev *hdev) |
83e81961 BYTK |
97 | { |
98 | struct sk_buff *skb; | |
99 | int err; | |
100 | ||
ba493d4f | 101 | bt_dev_dbg(hdev, "QCA HCI_RESET"); |
83e81961 BYTK |
102 | |
103 | skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT); | |
104 | if (IS_ERR(skb)) { | |
105 | err = PTR_ERR(skb); | |
ba493d4f | 106 | bt_dev_err(hdev, "QCA Reset failed (%d)", err); |
83e81961 BYTK |
107 | return err; |
108 | } | |
109 | ||
110 | kfree_skb(skb); | |
111 | ||
112 | return 0; | |
113 | } | |
114 | ||
ba493d4f | 115 | static void qca_tlv_check_data(struct rome_config *config, |
83e81961 BYTK |
116 | const struct firmware *fw) |
117 | { | |
118 | const u8 *data; | |
119 | u32 type_len; | |
120 | u16 tag_id, tag_len; | |
121 | int idx, length; | |
122 | struct tlv_type_hdr *tlv; | |
123 | struct tlv_type_patch *tlv_patch; | |
124 | struct tlv_type_nvm *tlv_nvm; | |
125 | ||
126 | tlv = (struct tlv_type_hdr *)fw->data; | |
127 | ||
128 | type_len = le32_to_cpu(tlv->type_len); | |
129 | length = (type_len >> 8) & 0x00ffffff; | |
130 | ||
131 | BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff); | |
132 | BT_DBG("Length\t\t : %d bytes", length); | |
133 | ||
6e03126a LP |
134 | config->dnld_mode = ROME_SKIP_EVT_NONE; |
135 | ||
83e81961 BYTK |
136 | switch (config->type) { |
137 | case TLV_TYPE_PATCH: | |
138 | tlv_patch = (struct tlv_type_patch *)tlv->data; | |
6e03126a LP |
139 | |
140 | /* For Rome version 1.1 to 3.1, all segment commands | |
141 | * are acked by a vendor specific event (VSE). | |
142 | * For Rome >= 3.2, the download mode field indicates | |
143 | * if VSE is skipped by the controller. | |
144 | * In case VSE is skipped, only the last segment is acked. | |
145 | */ | |
146 | config->dnld_mode = tlv_patch->download_mode; | |
147 | ||
148 | BT_DBG("Total Length : %d bytes", | |
83e81961 | 149 | le32_to_cpu(tlv_patch->total_size)); |
6e03126a | 150 | BT_DBG("Patch Data Length : %d bytes", |
83e81961 BYTK |
151 | le32_to_cpu(tlv_patch->data_length)); |
152 | BT_DBG("Signing Format Version : 0x%x", | |
153 | tlv_patch->format_version); | |
6e03126a | 154 | BT_DBG("Signature Algorithm : 0x%x", |
83e81961 | 155 | tlv_patch->signature); |
6e03126a LP |
156 | BT_DBG("Download mode : 0x%x", |
157 | tlv_patch->download_mode); | |
158 | BT_DBG("Reserved : 0x%x", | |
159 | tlv_patch->reserved1); | |
160 | BT_DBG("Product ID : 0x%04x", | |
83e81961 | 161 | le16_to_cpu(tlv_patch->product_id)); |
6e03126a | 162 | BT_DBG("Rom Build Version : 0x%04x", |
83e81961 | 163 | le16_to_cpu(tlv_patch->rom_build)); |
6e03126a | 164 | BT_DBG("Patch Version : 0x%04x", |
83e81961 | 165 | le16_to_cpu(tlv_patch->patch_version)); |
6e03126a | 166 | BT_DBG("Reserved : 0x%x", |
83e81961 | 167 | le16_to_cpu(tlv_patch->reserved2)); |
6e03126a | 168 | BT_DBG("Patch Entry Address : 0x%x", |
83e81961 BYTK |
169 | le32_to_cpu(tlv_patch->entry)); |
170 | break; | |
171 | ||
172 | case TLV_TYPE_NVM: | |
173 | idx = 0; | |
174 | data = tlv->data; | |
175 | while (idx < length) { | |
176 | tlv_nvm = (struct tlv_type_nvm *)(data + idx); | |
177 | ||
178 | tag_id = le16_to_cpu(tlv_nvm->tag_id); | |
179 | tag_len = le16_to_cpu(tlv_nvm->tag_len); | |
180 | ||
181 | /* Update NVM tags as needed */ | |
182 | switch (tag_id) { | |
183 | case EDL_TAG_ID_HCI: | |
184 | /* HCI transport layer parameters | |
185 | * enabling software inband sleep | |
186 | * onto controller side. | |
187 | */ | |
188 | tlv_nvm->data[0] |= 0x80; | |
189 | ||
190 | /* UART Baud Rate */ | |
191 | tlv_nvm->data[2] = config->user_baud_rate; | |
192 | ||
193 | break; | |
194 | ||
195 | case EDL_TAG_ID_DEEP_SLEEP: | |
196 | /* Sleep enable mask | |
197 | * enabling deep sleep feature on controller. | |
198 | */ | |
199 | tlv_nvm->data[0] |= 0x01; | |
200 | ||
201 | break; | |
202 | } | |
203 | ||
204 | idx += (sizeof(u16) + sizeof(u16) + 8 + tag_len); | |
205 | } | |
206 | break; | |
207 | ||
208 | default: | |
209 | BT_ERR("Unknown TLV type %d", config->type); | |
210 | break; | |
211 | } | |
212 | } | |
213 | ||
ba493d4f | 214 | static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, |
6e03126a | 215 | const u8 *data, enum rome_tlv_dnld_mode mode) |
83e81961 BYTK |
216 | { |
217 | struct sk_buff *skb; | |
218 | struct edl_event_hdr *edl; | |
219 | struct tlv_seg_resp *tlv_resp; | |
220 | u8 cmd[MAX_SIZE_PER_TLV_SEGMENT + 2]; | |
221 | int err = 0; | |
222 | ||
83e81961 BYTK |
223 | cmd[0] = EDL_PATCH_TLV_REQ_CMD; |
224 | cmd[1] = seg_size; | |
225 | memcpy(cmd + 2, data, seg_size); | |
226 | ||
6e03126a LP |
227 | if (mode == ROME_SKIP_EVT_VSE_CC || mode == ROME_SKIP_EVT_VSE) |
228 | return __hci_cmd_send(hdev, EDL_PATCH_CMD_OPCODE, seg_size + 2, | |
229 | cmd); | |
230 | ||
83e81961 BYTK |
231 | skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, seg_size + 2, cmd, |
232 | HCI_VENDOR_PKT, HCI_INIT_TIMEOUT); | |
233 | if (IS_ERR(skb)) { | |
234 | err = PTR_ERR(skb); | |
ba493d4f | 235 | bt_dev_err(hdev, "QCA Failed to send TLV segment (%d)", err); |
83e81961 BYTK |
236 | return err; |
237 | } | |
238 | ||
239 | if (skb->len != sizeof(*edl) + sizeof(*tlv_resp)) { | |
ba493d4f | 240 | bt_dev_err(hdev, "QCA TLV response size mismatch"); |
83e81961 BYTK |
241 | err = -EILSEQ; |
242 | goto out; | |
243 | } | |
244 | ||
245 | edl = (struct edl_event_hdr *)(skb->data); | |
0676cab4 | 246 | if (!edl) { |
ba493d4f | 247 | bt_dev_err(hdev, "TLV with no header"); |
83e81961 BYTK |
248 | err = -EILSEQ; |
249 | goto out; | |
250 | } | |
251 | ||
252 | tlv_resp = (struct tlv_seg_resp *)(edl->data); | |
253 | ||
254 | if (edl->cresp != EDL_CMD_REQ_RES_EVT || | |
255 | edl->rtype != EDL_TVL_DNLD_RES_EVT || tlv_resp->result != 0x00) { | |
ba493d4f BG |
256 | bt_dev_err(hdev, "QCA TLV with error stat 0x%x rtype 0x%x (0x%x)", |
257 | edl->cresp, edl->rtype, tlv_resp->result); | |
83e81961 BYTK |
258 | err = -EIO; |
259 | } | |
260 | ||
261 | out: | |
262 | kfree_skb(skb); | |
263 | ||
264 | return err; | |
265 | } | |
266 | ||
ba493d4f | 267 | static int qca_download_firmware(struct hci_dev *hdev, |
83e81961 BYTK |
268 | struct rome_config *config) |
269 | { | |
270 | const struct firmware *fw; | |
6e03126a LP |
271 | const u8 *segment; |
272 | int ret, remain, i = 0; | |
83e81961 | 273 | |
ba493d4f | 274 | bt_dev_info(hdev, "QCA Downloading %s", config->fwname); |
83e81961 BYTK |
275 | |
276 | ret = request_firmware(&fw, config->fwname, &hdev->dev); | |
277 | if (ret) { | |
ba493d4f BG |
278 | bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", |
279 | config->fwname, ret); | |
83e81961 BYTK |
280 | return ret; |
281 | } | |
282 | ||
ba493d4f | 283 | qca_tlv_check_data(config, fw); |
83e81961 | 284 | |
6e03126a LP |
285 | segment = fw->data; |
286 | remain = fw->size; | |
287 | while (remain > 0) { | |
288 | int segsize = min(MAX_SIZE_PER_TLV_SEGMENT, remain); | |
289 | ||
290 | bt_dev_dbg(hdev, "Send segment %d, size %d", i++, segsize); | |
291 | ||
292 | remain -= segsize; | |
293 | /* The last segment is always acked regardless download mode */ | |
294 | if (!remain || segsize < MAX_SIZE_PER_TLV_SEGMENT) | |
295 | config->dnld_mode = ROME_SKIP_EVT_NONE; | |
296 | ||
ba493d4f | 297 | ret = qca_tlv_send_segment(hdev, segsize, segment, |
6e03126a LP |
298 | config->dnld_mode); |
299 | if (ret) | |
300 | break; | |
301 | ||
302 | segment += segsize; | |
83e81961 BYTK |
303 | } |
304 | ||
305 | release_firmware(fw); | |
306 | ||
307 | return ret; | |
308 | } | |
309 | ||
310 | int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) | |
311 | { | |
312 | struct sk_buff *skb; | |
313 | u8 cmd[9]; | |
314 | int err; | |
315 | ||
316 | cmd[0] = EDL_NVM_ACCESS_SET_REQ_CMD; | |
317 | cmd[1] = 0x02; /* TAG ID */ | |
318 | cmd[2] = sizeof(bdaddr_t); /* size */ | |
319 | memcpy(cmd + 3, bdaddr, sizeof(bdaddr_t)); | |
320 | skb = __hci_cmd_sync_ev(hdev, EDL_NVM_ACCESS_OPCODE, sizeof(cmd), cmd, | |
321 | HCI_VENDOR_PKT, HCI_INIT_TIMEOUT); | |
322 | if (IS_ERR(skb)) { | |
323 | err = PTR_ERR(skb); | |
ba493d4f | 324 | bt_dev_err(hdev, "QCA Change address command failed (%d)", err); |
83e81961 BYTK |
325 | return err; |
326 | } | |
327 | ||
328 | kfree_skb(skb); | |
329 | ||
330 | return 0; | |
331 | } | |
332 | EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); | |
333 | ||
aadebac4 BG |
334 | int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, |
335 | enum qca_btsoc_type soc_type, u32 soc_ver) | |
83e81961 | 336 | { |
83e81961 BYTK |
337 | struct rome_config config; |
338 | int err; | |
4219d468 | 339 | u8 rom_ver; |
83e81961 | 340 | |
ba493d4f | 341 | bt_dev_dbg(hdev, "QCA setup on UART"); |
83e81961 BYTK |
342 | |
343 | config.user_baud_rate = baudrate; | |
344 | ||
83e81961 BYTK |
345 | /* Download rampatch file */ |
346 | config.type = TLV_TYPE_PATCH; | |
4219d468 BG |
347 | if (soc_type == QCA_WCN3990) { |
348 | /* Firmware files to download are based on ROM version. | |
349 | * ROM version is derived from last two bytes of soc_ver. | |
350 | */ | |
351 | rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | | |
352 | (soc_ver & 0x0000000f); | |
353 | snprintf(config.fwname, sizeof(config.fwname), | |
354 | "qca/crbtfw%02x.tlv", rom_ver); | |
355 | } else { | |
356 | snprintf(config.fwname, sizeof(config.fwname), | |
357 | "qca/rampatch_%08x.bin", soc_ver); | |
358 | } | |
359 | ||
ba493d4f | 360 | err = qca_download_firmware(hdev, &config); |
83e81961 | 361 | if (err < 0) { |
ba493d4f | 362 | bt_dev_err(hdev, "QCA Failed to download patch (%d)", err); |
83e81961 BYTK |
363 | return err; |
364 | } | |
365 | ||
366 | /* Download NVM configuration */ | |
367 | config.type = TLV_TYPE_NVM; | |
4219d468 BG |
368 | if (soc_type == QCA_WCN3990) |
369 | snprintf(config.fwname, sizeof(config.fwname), | |
370 | "qca/crnv%02x.bin", rom_ver); | |
371 | else | |
372 | snprintf(config.fwname, sizeof(config.fwname), | |
373 | "qca/nvm_%08x.bin", soc_ver); | |
374 | ||
ba493d4f | 375 | err = qca_download_firmware(hdev, &config); |
83e81961 | 376 | if (err < 0) { |
ba493d4f | 377 | bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err); |
83e81961 BYTK |
378 | return err; |
379 | } | |
380 | ||
381 | /* Perform HCI reset */ | |
ba493d4f | 382 | err = qca_send_reset(hdev); |
83e81961 | 383 | if (err < 0) { |
ba493d4f | 384 | bt_dev_err(hdev, "QCA Failed to run HCI_RESET (%d)", err); |
83e81961 BYTK |
385 | return err; |
386 | } | |
387 | ||
ba493d4f | 388 | bt_dev_info(hdev, "QCA setup on UART is completed"); |
83e81961 BYTK |
389 | |
390 | return 0; | |
391 | } | |
ba493d4f | 392 | EXPORT_SYMBOL_GPL(qca_uart_setup); |
83e81961 BYTK |
393 | |
394 | MODULE_AUTHOR("Ben Young Tae Kim <ytkim@qca.qualcomm.com>"); | |
395 | MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " VERSION); | |
396 | MODULE_VERSION(VERSION); | |
397 | MODULE_LICENSE("GPL"); |