Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: btqca: Introduce generic QCA ROME support

This is for supporting BT for QCA ROME with vendor specific
HCI commands and initialization on the chip. This will have
USB/UART implementation both, but for now, adding UART vendor
specific commands to patch downloading and set Bluetooth device
address using vendor specific command.

Signed-off-by: Ben Young Tae Kim <ytkim@qca.qualcomm.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Ben Young Tae Kim and committed by
Marcel Holtmann
83e81961 fa142220

+532
+4
drivers/bluetooth/Kconfig
··· 13 13 tristate 14 14 select FW_LOADER 15 15 16 + config BT_QCA 17 + tristate 18 + select FW_LOADER 19 + 16 20 config BT_HCIBTUSB 17 21 tristate "HCI USB driver" 18 22 depends on USB
+1
drivers/bluetooth/Makefile
··· 22 22 obj-$(CONFIG_BT_WILINK) += btwilink.o 23 23 obj-$(CONFIG_BT_BCM) += btbcm.o 24 24 obj-$(CONFIG_BT_RTL) += btrtl.o 25 + obj-$(CONFIG_BT_QCA) += btqca.o 25 26 26 27 btmrvl-y := btmrvl_main.o 27 28 btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o
+392
drivers/bluetooth/btqca.c
··· 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 + 30 + static int rome_patch_ver_req(struct hci_dev *hdev, u32 *rome_version) 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 + 38 + BT_DBG("%s: ROME Patch Version Request", hdev->name); 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); 45 + BT_ERR("%s: Failed to read version of ROME (%d)", hdev->name, 46 + err); 47 + return err; 48 + } 49 + 50 + if (skb->len != sizeof(*edl) + sizeof(*ver)) { 51 + BT_ERR("%s: Version size mismatch len %d", hdev->name, 52 + skb->len); 53 + err = -EILSEQ; 54 + goto out; 55 + } 56 + 57 + edl = (struct edl_event_hdr *)(skb->data); 58 + if (!edl || !edl->data) { 59 + BT_ERR("%s: TLV with no header or no data", hdev->name); 60 + err = -EILSEQ; 61 + goto out; 62 + } 63 + 64 + if (edl->cresp != EDL_CMD_REQ_RES_EVT || 65 + edl->rtype != EDL_APP_VER_RES_EVT) { 66 + BT_ERR("%s: Wrong packet received %d %d", hdev->name, 67 + edl->cresp, edl->rtype); 68 + err = -EIO; 69 + goto out; 70 + } 71 + 72 + ver = (struct rome_version *)(edl->data); 73 + 74 + BT_DBG("%s: Product:0x%08x", hdev->name, le32_to_cpu(ver->product_id)); 75 + BT_DBG("%s: Patch :0x%08x", hdev->name, le16_to_cpu(ver->patch_ver)); 76 + BT_DBG("%s: ROM :0x%08x", hdev->name, le16_to_cpu(ver->rome_ver)); 77 + BT_DBG("%s: SOC :0x%08x", hdev->name, le32_to_cpu(ver->soc_id)); 78 + 79 + /* ROME chipset version can be decided by patch and SoC 80 + * version, combination with upper 2 bytes from SoC 81 + * and lower 2 bytes from patch will be used. 82 + */ 83 + *rome_version = (le32_to_cpu(ver->soc_id) << 16) | 84 + (le16_to_cpu(ver->rome_ver) & 0x0000ffff); 85 + 86 + out: 87 + kfree_skb(skb); 88 + 89 + return err; 90 + } 91 + 92 + static int rome_reset(struct hci_dev *hdev) 93 + { 94 + struct sk_buff *skb; 95 + int err; 96 + 97 + BT_DBG("%s: ROME HCI_RESET", hdev->name); 98 + 99 + skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT); 100 + if (IS_ERR(skb)) { 101 + err = PTR_ERR(skb); 102 + BT_ERR("%s: Reset failed (%d)", hdev->name, err); 103 + return err; 104 + } 105 + 106 + kfree_skb(skb); 107 + 108 + return 0; 109 + } 110 + 111 + static void rome_tlv_check_data(struct rome_config *config, 112 + const struct firmware *fw) 113 + { 114 + const u8 *data; 115 + u32 type_len; 116 + u16 tag_id, tag_len; 117 + int idx, length; 118 + struct tlv_type_hdr *tlv; 119 + struct tlv_type_patch *tlv_patch; 120 + struct tlv_type_nvm *tlv_nvm; 121 + 122 + tlv = (struct tlv_type_hdr *)fw->data; 123 + 124 + type_len = le32_to_cpu(tlv->type_len); 125 + length = (type_len >> 8) & 0x00ffffff; 126 + 127 + BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff); 128 + BT_DBG("Length\t\t : %d bytes", length); 129 + 130 + switch (config->type) { 131 + case TLV_TYPE_PATCH: 132 + tlv_patch = (struct tlv_type_patch *)tlv->data; 133 + BT_DBG("Total Length\t\t : %d bytes", 134 + le32_to_cpu(tlv_patch->total_size)); 135 + BT_DBG("Patch Data Length\t : %d bytes", 136 + le32_to_cpu(tlv_patch->data_length)); 137 + BT_DBG("Signing Format Version : 0x%x", 138 + tlv_patch->format_version); 139 + BT_DBG("Signature Algorithm\t : 0x%x", 140 + tlv_patch->signature); 141 + BT_DBG("Reserved\t\t : 0x%x", 142 + le16_to_cpu(tlv_patch->reserved1)); 143 + BT_DBG("Product ID\t\t : 0x%04x", 144 + le16_to_cpu(tlv_patch->product_id)); 145 + BT_DBG("Rom Build Version\t : 0x%04x", 146 + le16_to_cpu(tlv_patch->rom_build)); 147 + BT_DBG("Patch Version\t\t : 0x%04x", 148 + le16_to_cpu(tlv_patch->patch_version)); 149 + BT_DBG("Reserved\t\t : 0x%x", 150 + le16_to_cpu(tlv_patch->reserved2)); 151 + BT_DBG("Patch Entry Address\t : 0x%x", 152 + le32_to_cpu(tlv_patch->entry)); 153 + break; 154 + 155 + case TLV_TYPE_NVM: 156 + idx = 0; 157 + data = tlv->data; 158 + while (idx < length) { 159 + tlv_nvm = (struct tlv_type_nvm *)(data + idx); 160 + 161 + tag_id = le16_to_cpu(tlv_nvm->tag_id); 162 + tag_len = le16_to_cpu(tlv_nvm->tag_len); 163 + 164 + /* Update NVM tags as needed */ 165 + switch (tag_id) { 166 + case EDL_TAG_ID_HCI: 167 + /* HCI transport layer parameters 168 + * enabling software inband sleep 169 + * onto controller side. 170 + */ 171 + tlv_nvm->data[0] |= 0x80; 172 + 173 + /* UART Baud Rate */ 174 + tlv_nvm->data[2] = config->user_baud_rate; 175 + 176 + break; 177 + 178 + case EDL_TAG_ID_DEEP_SLEEP: 179 + /* Sleep enable mask 180 + * enabling deep sleep feature on controller. 181 + */ 182 + tlv_nvm->data[0] |= 0x01; 183 + 184 + break; 185 + } 186 + 187 + idx += (sizeof(u16) + sizeof(u16) + 8 + tag_len); 188 + } 189 + break; 190 + 191 + default: 192 + BT_ERR("Unknown TLV type %d", config->type); 193 + break; 194 + } 195 + } 196 + 197 + static int rome_tlv_send_segment(struct hci_dev *hdev, int idx, int seg_size, 198 + const u8 *data) 199 + { 200 + struct sk_buff *skb; 201 + struct edl_event_hdr *edl; 202 + struct tlv_seg_resp *tlv_resp; 203 + u8 cmd[MAX_SIZE_PER_TLV_SEGMENT + 2]; 204 + int err = 0; 205 + 206 + BT_DBG("%s: Download segment #%d size %d", hdev->name, idx, seg_size); 207 + 208 + cmd[0] = EDL_PATCH_TLV_REQ_CMD; 209 + cmd[1] = seg_size; 210 + memcpy(cmd + 2, data, seg_size); 211 + 212 + skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, seg_size + 2, cmd, 213 + HCI_VENDOR_PKT, HCI_INIT_TIMEOUT); 214 + if (IS_ERR(skb)) { 215 + err = PTR_ERR(skb); 216 + BT_ERR("%s: Failed to send TLV segment (%d)", hdev->name, err); 217 + return err; 218 + } 219 + 220 + if (skb->len != sizeof(*edl) + sizeof(*tlv_resp)) { 221 + BT_ERR("%s: TLV response size mismatch", hdev->name); 222 + err = -EILSEQ; 223 + goto out; 224 + } 225 + 226 + edl = (struct edl_event_hdr *)(skb->data); 227 + if (!edl || !edl->data) { 228 + BT_ERR("%s: TLV with no header or no data", hdev->name); 229 + err = -EILSEQ; 230 + goto out; 231 + } 232 + 233 + tlv_resp = (struct tlv_seg_resp *)(edl->data); 234 + 235 + if (edl->cresp != EDL_CMD_REQ_RES_EVT || 236 + edl->rtype != EDL_TVL_DNLD_RES_EVT || tlv_resp->result != 0x00) { 237 + BT_ERR("%s: TLV with error stat 0x%x rtype 0x%x (0x%x)", 238 + hdev->name, edl->cresp, edl->rtype, tlv_resp->result); 239 + err = -EIO; 240 + } 241 + 242 + out: 243 + kfree_skb(skb); 244 + 245 + return err; 246 + } 247 + 248 + static int rome_tlv_download_request(struct hci_dev *hdev, 249 + const struct firmware *fw) 250 + { 251 + const u8 *buffer, *data; 252 + int total_segment, remain_size; 253 + int ret, i; 254 + 255 + if (!fw || !fw->data) 256 + return -EINVAL; 257 + 258 + total_segment = fw->size / MAX_SIZE_PER_TLV_SEGMENT; 259 + remain_size = fw->size % MAX_SIZE_PER_TLV_SEGMENT; 260 + 261 + BT_DBG("%s: Total segment num %d remain size %d total size %zu", 262 + hdev->name, total_segment, remain_size, fw->size); 263 + 264 + data = fw->data; 265 + for (i = 0; i < total_segment; i++) { 266 + buffer = data + i * MAX_SIZE_PER_TLV_SEGMENT; 267 + ret = rome_tlv_send_segment(hdev, i, MAX_SIZE_PER_TLV_SEGMENT, 268 + buffer); 269 + if (ret < 0) 270 + return -EIO; 271 + } 272 + 273 + if (remain_size) { 274 + buffer = data + total_segment * MAX_SIZE_PER_TLV_SEGMENT; 275 + ret = rome_tlv_send_segment(hdev, total_segment, remain_size, 276 + buffer); 277 + if (ret < 0) 278 + return -EIO; 279 + } 280 + 281 + return 0; 282 + } 283 + 284 + static int rome_download_firmware(struct hci_dev *hdev, 285 + struct rome_config *config) 286 + { 287 + const struct firmware *fw; 288 + int ret; 289 + 290 + BT_INFO("%s: ROME Downloading %s", hdev->name, config->fwname); 291 + 292 + ret = request_firmware(&fw, config->fwname, &hdev->dev); 293 + if (ret) { 294 + BT_ERR("%s: Failed to request file: %s (%d)", hdev->name, 295 + config->fwname, ret); 296 + return ret; 297 + } 298 + 299 + rome_tlv_check_data(config, fw); 300 + 301 + ret = rome_tlv_download_request(hdev, fw); 302 + if (ret) { 303 + BT_ERR("%s: Failed to download file: %s (%d)", hdev->name, 304 + config->fwname, ret); 305 + } 306 + 307 + release_firmware(fw); 308 + 309 + return ret; 310 + } 311 + 312 + int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) 313 + { 314 + struct sk_buff *skb; 315 + u8 cmd[9]; 316 + int err; 317 + 318 + cmd[0] = EDL_NVM_ACCESS_SET_REQ_CMD; 319 + cmd[1] = 0x02; /* TAG ID */ 320 + cmd[2] = sizeof(bdaddr_t); /* size */ 321 + memcpy(cmd + 3, bdaddr, sizeof(bdaddr_t)); 322 + skb = __hci_cmd_sync_ev(hdev, EDL_NVM_ACCESS_OPCODE, sizeof(cmd), cmd, 323 + HCI_VENDOR_PKT, HCI_INIT_TIMEOUT); 324 + if (IS_ERR(skb)) { 325 + err = PTR_ERR(skb); 326 + BT_ERR("%s: Change address command failed (%d)", 327 + hdev->name, err); 328 + return err; 329 + } 330 + 331 + kfree_skb(skb); 332 + 333 + return 0; 334 + } 335 + EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); 336 + 337 + int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate) 338 + { 339 + u32 rome_ver = 0; 340 + struct rome_config config; 341 + int err; 342 + 343 + BT_DBG("%s: ROME setup on UART", hdev->name); 344 + 345 + config.user_baud_rate = baudrate; 346 + 347 + /* Get ROME version information */ 348 + err = rome_patch_ver_req(hdev, &rome_ver); 349 + if (err < 0 || rome_ver == 0) { 350 + BT_ERR("%s: Failed to get version 0x%x", hdev->name, err); 351 + return err; 352 + } 353 + 354 + BT_INFO("%s: ROME controller version 0x%08x", hdev->name, rome_ver); 355 + 356 + /* Download rampatch file */ 357 + config.type = TLV_TYPE_PATCH; 358 + snprintf(config.fwname, sizeof(config.fwname), "qca/rampatch_%08x.bin", 359 + rome_ver); 360 + err = rome_download_firmware(hdev, &config); 361 + if (err < 0) { 362 + BT_ERR("%s: Failed to download patch (%d)", hdev->name, err); 363 + return err; 364 + } 365 + 366 + /* Download NVM configuration */ 367 + config.type = TLV_TYPE_NVM; 368 + snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin", 369 + rome_ver); 370 + err = rome_download_firmware(hdev, &config); 371 + if (err < 0) { 372 + BT_ERR("%s: Failed to download NVM (%d)", hdev->name, err); 373 + return err; 374 + } 375 + 376 + /* Perform HCI reset */ 377 + err = rome_reset(hdev); 378 + if (err < 0) { 379 + BT_ERR("%s: Failed to run HCI_RESET (%d)", hdev->name, err); 380 + return err; 381 + } 382 + 383 + BT_INFO("%s: ROME setup on UART is completed", hdev->name); 384 + 385 + return 0; 386 + } 387 + EXPORT_SYMBOL_GPL(qca_uart_setup_rome); 388 + 389 + MODULE_AUTHOR("Ben Young Tae Kim <ytkim@qca.qualcomm.com>"); 390 + MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " VERSION); 391 + MODULE_VERSION(VERSION); 392 + MODULE_LICENSE("GPL");
+135
drivers/bluetooth/btqca.h
··· 1 + /* 2 + * Bluetooth supports for Qualcomm Atheros ROME 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 + 21 + #define EDL_PATCH_CMD_OPCODE (0xFC00) 22 + #define EDL_NVM_ACCESS_OPCODE (0xFC0B) 23 + #define EDL_PATCH_CMD_LEN (1) 24 + #define EDL_PATCH_VER_REQ_CMD (0x19) 25 + #define EDL_PATCH_TLV_REQ_CMD (0x1E) 26 + #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) 27 + #define MAX_SIZE_PER_TLV_SEGMENT (243) 28 + 29 + #define EDL_CMD_REQ_RES_EVT (0x00) 30 + #define EDL_PATCH_VER_RES_EVT (0x19) 31 + #define EDL_APP_VER_RES_EVT (0x02) 32 + #define EDL_TVL_DNLD_RES_EVT (0x04) 33 + #define EDL_CMD_EXE_STATUS_EVT (0x00) 34 + #define EDL_SET_BAUDRATE_RSP_EVT (0x92) 35 + #define EDL_NVM_ACCESS_CODE_EVT (0x0B) 36 + 37 + #define EDL_TAG_ID_HCI (17) 38 + #define EDL_TAG_ID_DEEP_SLEEP (27) 39 + 40 + enum qca_bardrate { 41 + QCA_BAUDRATE_115200 = 0, 42 + QCA_BAUDRATE_57600, 43 + QCA_BAUDRATE_38400, 44 + QCA_BAUDRATE_19200, 45 + QCA_BAUDRATE_9600, 46 + QCA_BAUDRATE_230400, 47 + QCA_BAUDRATE_250000, 48 + QCA_BAUDRATE_460800, 49 + QCA_BAUDRATE_500000, 50 + QCA_BAUDRATE_720000, 51 + QCA_BAUDRATE_921600, 52 + QCA_BAUDRATE_1000000, 53 + QCA_BAUDRATE_1250000, 54 + QCA_BAUDRATE_2000000, 55 + QCA_BAUDRATE_3000000, 56 + QCA_BAUDRATE_4000000, 57 + QCA_BAUDRATE_1600000, 58 + QCA_BAUDRATE_3200000, 59 + QCA_BAUDRATE_3500000, 60 + QCA_BAUDRATE_AUTO = 0xFE, 61 + QCA_BAUDRATE_RESERVED 62 + }; 63 + 64 + enum rome_tlv_type { 65 + TLV_TYPE_PATCH = 1, 66 + TLV_TYPE_NVM 67 + }; 68 + 69 + struct rome_config { 70 + u8 type; 71 + char fwname[64]; 72 + uint8_t user_baud_rate; 73 + }; 74 + 75 + struct edl_event_hdr { 76 + __u8 cresp; 77 + __u8 rtype; 78 + __u8 data[0]; 79 + } __packed; 80 + 81 + struct rome_version { 82 + __le32 product_id; 83 + __le16 patch_ver; 84 + __le16 rome_ver; 85 + __le32 soc_id; 86 + } __packed; 87 + 88 + struct tlv_seg_resp { 89 + __u8 result; 90 + } __packed; 91 + 92 + struct tlv_type_patch { 93 + __le32 total_size; 94 + __le32 data_length; 95 + __u8 format_version; 96 + __u8 signature; 97 + __le16 reserved1; 98 + __le16 product_id; 99 + __le16 rom_build; 100 + __le16 patch_version; 101 + __le16 reserved2; 102 + __le32 entry; 103 + } __packed; 104 + 105 + struct tlv_type_nvm { 106 + __le16 tag_id; 107 + __le16 tag_len; 108 + __le32 reserve1; 109 + __le32 reserve2; 110 + __u8 data[0]; 111 + } __packed; 112 + 113 + struct tlv_type_hdr { 114 + __le32 type_len; 115 + __u8 data[0]; 116 + } __packed; 117 + 118 + #if IS_ENABLED(CONFIG_BT_QCA) 119 + 120 + int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr); 121 + int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate); 122 + 123 + #else 124 + 125 + static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) 126 + { 127 + return -EOPNOTSUPP; 128 + } 129 + 130 + static inline int qca_uart_setup_rome(struct hci_dev *hdev, int speed) 131 + { 132 + return -EOPNOTSUPP; 133 + } 134 + 135 + #endif