hci_ag6xx.c (7241B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * 4 * Bluetooth HCI UART driver for Intel/AG6xx devices 5 * 6 * Copyright (C) 2016 Intel Corporation 7 */ 8 9#include <linux/kernel.h> 10#include <linux/errno.h> 11#include <linux/skbuff.h> 12#include <linux/firmware.h> 13#include <linux/module.h> 14#include <linux/tty.h> 15 16#include <net/bluetooth/bluetooth.h> 17#include <net/bluetooth/hci_core.h> 18 19#include "hci_uart.h" 20#include "btintel.h" 21 22struct ag6xx_data { 23 struct sk_buff *rx_skb; 24 struct sk_buff_head txq; 25}; 26 27struct pbn_entry { 28 __le32 addr; 29 __le32 plen; 30 __u8 data[]; 31} __packed; 32 33static int ag6xx_open(struct hci_uart *hu) 34{ 35 struct ag6xx_data *ag6xx; 36 37 BT_DBG("hu %p", hu); 38 39 ag6xx = kzalloc(sizeof(*ag6xx), GFP_KERNEL); 40 if (!ag6xx) 41 return -ENOMEM; 42 43 skb_queue_head_init(&ag6xx->txq); 44 45 hu->priv = ag6xx; 46 return 0; 47} 48 49static int ag6xx_close(struct hci_uart *hu) 50{ 51 struct ag6xx_data *ag6xx = hu->priv; 52 53 BT_DBG("hu %p", hu); 54 55 skb_queue_purge(&ag6xx->txq); 56 kfree_skb(ag6xx->rx_skb); 57 kfree(ag6xx); 58 59 hu->priv = NULL; 60 return 0; 61} 62 63static int ag6xx_flush(struct hci_uart *hu) 64{ 65 struct ag6xx_data *ag6xx = hu->priv; 66 67 BT_DBG("hu %p", hu); 68 69 skb_queue_purge(&ag6xx->txq); 70 return 0; 71} 72 73static struct sk_buff *ag6xx_dequeue(struct hci_uart *hu) 74{ 75 struct ag6xx_data *ag6xx = hu->priv; 76 struct sk_buff *skb; 77 78 skb = skb_dequeue(&ag6xx->txq); 79 if (!skb) 80 return skb; 81 82 /* Prepend skb with frame type */ 83 memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); 84 return skb; 85} 86 87static int ag6xx_enqueue(struct hci_uart *hu, struct sk_buff *skb) 88{ 89 struct ag6xx_data *ag6xx = hu->priv; 90 91 skb_queue_tail(&ag6xx->txq, skb); 92 return 0; 93} 94 95static const struct h4_recv_pkt ag6xx_recv_pkts[] = { 96 { H4_RECV_ACL, .recv = hci_recv_frame }, 97 { H4_RECV_SCO, .recv = hci_recv_frame }, 98 { H4_RECV_EVENT, .recv = hci_recv_frame }, 99}; 100 101static int ag6xx_recv(struct hci_uart *hu, const void *data, int count) 102{ 103 struct ag6xx_data *ag6xx = hu->priv; 104 105 if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) 106 return -EUNATCH; 107 108 ag6xx->rx_skb = h4_recv_buf(hu->hdev, ag6xx->rx_skb, data, count, 109 ag6xx_recv_pkts, 110 ARRAY_SIZE(ag6xx_recv_pkts)); 111 if (IS_ERR(ag6xx->rx_skb)) { 112 int err = PTR_ERR(ag6xx->rx_skb); 113 bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err); 114 ag6xx->rx_skb = NULL; 115 return err; 116 } 117 118 return count; 119} 120 121static int intel_mem_write(struct hci_dev *hdev, u32 addr, u32 plen, 122 const void *data) 123{ 124 /* Can write a maximum of 247 bytes per HCI command. 125 * HCI cmd Header (3), Intel mem write header (6), data (247). 126 */ 127 while (plen > 0) { 128 struct sk_buff *skb; 129 u8 cmd_param[253], fragment_len = (plen > 247) ? 247 : plen; 130 __le32 leaddr = cpu_to_le32(addr); 131 132 memcpy(cmd_param, &leaddr, 4); 133 cmd_param[4] = 0; 134 cmd_param[5] = fragment_len; 135 memcpy(cmd_param + 6, data, fragment_len); 136 137 skb = __hci_cmd_sync(hdev, 0xfc8e, fragment_len + 6, cmd_param, 138 HCI_INIT_TIMEOUT); 139 if (IS_ERR(skb)) 140 return PTR_ERR(skb); 141 kfree_skb(skb); 142 143 plen -= fragment_len; 144 data += fragment_len; 145 addr += fragment_len; 146 } 147 148 return 0; 149} 150 151static int ag6xx_setup(struct hci_uart *hu) 152{ 153 struct hci_dev *hdev = hu->hdev; 154 struct sk_buff *skb; 155 struct intel_version ver; 156 const struct firmware *fw; 157 const u8 *fw_ptr; 158 char fwname[64]; 159 bool patched = false; 160 int err; 161 162 hu->hdev->set_diag = btintel_set_diag; 163 hu->hdev->set_bdaddr = btintel_set_bdaddr; 164 165 err = btintel_enter_mfg(hdev); 166 if (err) 167 return err; 168 169 err = btintel_read_version(hdev, &ver); 170 if (err) 171 return err; 172 173 btintel_version_info(hdev, &ver); 174 175 /* The hardware platform number has a fixed value of 0x37 and 176 * for now only accept this single value. 177 */ 178 if (ver.hw_platform != 0x37) { 179 bt_dev_err(hdev, "Unsupported Intel hardware platform: 0x%X", 180 ver.hw_platform); 181 return -EINVAL; 182 } 183 184 /* Only the hardware variant iBT 2.1 (AG6XX) is supported by this 185 * firmware setup method. 186 */ 187 if (ver.hw_variant != 0x0a) { 188 bt_dev_err(hdev, "Unsupported Intel hardware variant: 0x%x", 189 ver.hw_variant); 190 return -EINVAL; 191 } 192 193 snprintf(fwname, sizeof(fwname), "intel/ibt-hw-%x.%x.bddata", 194 ver.hw_platform, ver.hw_variant); 195 196 err = request_firmware(&fw, fwname, &hdev->dev); 197 if (err < 0) { 198 bt_dev_err(hdev, "Failed to open Intel bddata file: %s (%d)", 199 fwname, err); 200 goto patch; 201 } 202 203 bt_dev_info(hdev, "Applying bddata (%s)", fwname); 204 205 skb = __hci_cmd_sync_ev(hdev, 0xfc2f, fw->size, fw->data, 206 HCI_EV_CMD_STATUS, HCI_CMD_TIMEOUT); 207 if (IS_ERR(skb)) { 208 bt_dev_err(hdev, "Applying bddata failed (%ld)", PTR_ERR(skb)); 209 release_firmware(fw); 210 return PTR_ERR(skb); 211 } 212 kfree_skb(skb); 213 214 release_firmware(fw); 215 216patch: 217 /* If there is no applied patch, fw_patch_num is always 0x00. In other 218 * cases, current firmware is already patched. No need to patch it. 219 */ 220 if (ver.fw_patch_num) { 221 bt_dev_info(hdev, "Device is already patched. patch num: %02x", 222 ver.fw_patch_num); 223 patched = true; 224 goto complete; 225 } 226 227 snprintf(fwname, sizeof(fwname), 228 "intel/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.pbn", 229 ver.hw_platform, ver.hw_variant, ver.hw_revision, 230 ver.fw_variant, ver.fw_revision, ver.fw_build_num, 231 ver.fw_build_ww, ver.fw_build_yy); 232 233 err = request_firmware(&fw, fwname, &hdev->dev); 234 if (err < 0) { 235 bt_dev_err(hdev, "Failed to open Intel patch file: %s(%d)", 236 fwname, err); 237 goto complete; 238 } 239 fw_ptr = fw->data; 240 241 bt_dev_info(hdev, "Patching firmware file (%s)", fwname); 242 243 /* PBN patch file contains a list of binary patches to be applied on top 244 * of the embedded firmware. Each patch entry header contains the target 245 * address and patch size. 246 * 247 * Patch entry: 248 * | addr(le) | patch_len(le) | patch_data | 249 * | 4 Bytes | 4 Bytes | n Bytes | 250 * 251 * PBN file is terminated by a patch entry whose address is 0xffffffff. 252 */ 253 while (fw->size > fw_ptr - fw->data) { 254 struct pbn_entry *pbn = (void *)fw_ptr; 255 u32 addr, plen; 256 257 if (pbn->addr == 0xffffffff) { 258 bt_dev_info(hdev, "Patching complete"); 259 patched = true; 260 break; 261 } 262 263 addr = le32_to_cpu(pbn->addr); 264 plen = le32_to_cpu(pbn->plen); 265 266 if (fw->data + fw->size <= pbn->data + plen) { 267 bt_dev_info(hdev, "Invalid patch len (%d)", plen); 268 break; 269 } 270 271 bt_dev_info(hdev, "Patching %td/%zu", (fw_ptr - fw->data), 272 fw->size); 273 274 err = intel_mem_write(hdev, addr, plen, pbn->data); 275 if (err) { 276 bt_dev_err(hdev, "Patching failed"); 277 break; 278 } 279 280 fw_ptr = pbn->data + plen; 281 } 282 283 release_firmware(fw); 284 285complete: 286 /* Exit manufacturing mode and reset */ 287 err = btintel_exit_mfg(hdev, true, patched); 288 if (err) 289 return err; 290 291 /* Set the event mask for Intel specific vendor events. This enables 292 * a few extra events that are useful during general operation. 293 */ 294 btintel_set_event_mask_mfg(hdev, false); 295 296 btintel_check_bdaddr(hdev); 297 return 0; 298} 299 300static const struct hci_uart_proto ag6xx_proto = { 301 .id = HCI_UART_AG6XX, 302 .name = "AG6XX", 303 .manufacturer = 2, 304 .open = ag6xx_open, 305 .close = ag6xx_close, 306 .flush = ag6xx_flush, 307 .setup = ag6xx_setup, 308 .recv = ag6xx_recv, 309 .enqueue = ag6xx_enqueue, 310 .dequeue = ag6xx_dequeue, 311}; 312 313int __init ag6xx_init(void) 314{ 315 return hci_uart_register_proto(&ag6xx_proto); 316} 317 318int __exit ag6xx_deinit(void) 319{ 320 return hci_uart_unregister_proto(&ag6xx_proto); 321}