diff options
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/Kconfig | 11 | ||||
-rw-r--r-- | drivers/bluetooth/Makefile | 1 | ||||
-rw-r--r-- | drivers/bluetooth/btbcm.c | 10 | ||||
-rw-r--r-- | drivers/bluetooth/btintel.c | 45 | ||||
-rw-r--r-- | drivers/bluetooth/btintel.h | 5 | ||||
-rw-r--r-- | drivers/bluetooth/btmtksdio.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/btqca.c | 92 | ||||
-rw-r--r-- | drivers/bluetooth/btqca.h | 32 | ||||
-rw-r--r-- | drivers/bluetooth/btrtl.c | 4 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 57 | ||||
-rw-r--r-- | drivers/bluetooth/btwilink.c | 337 | ||||
-rw-r--r-- | drivers/bluetooth/hci_bcm.c | 4 | ||||
-rw-r--r-- | drivers/bluetooth/hci_bcsp.c | 3 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ll.c | 39 | ||||
-rw-r--r-- | drivers/bluetooth/hci_nokia.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/hci_qca.c | 278 |
16 files changed, 399 insertions, 522 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index aae665a3a254..f7aa2dc1ff85 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -380,17 +380,6 @@ config BT_ATH3K Say Y here to compile support for "Atheros firmware download driver" into the kernel or say M to compile it as module (ath3k). -config BT_WILINK - tristate "Texas Instruments WiLink7 driver" - depends on TI_ST - help - This enables the Bluetooth driver for Texas Instrument's BT/FM/GPS - combo devices. This makes use of shared transport line discipline - core driver to communicate with the BT core of the combo chip. - - Say Y here to compile support for Texas Instrument's WiLink7 driver - into the kernel or say M to compile it as module (btwilink). - config BT_MTKSDIO tristate "MediaTek HCI SDIO driver" depends on MMC diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile index 34887b9b3a85..1a58a3ae142c 100644 --- a/drivers/bluetooth/Makefile +++ b/drivers/bluetooth/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_BT_INTEL) += btintel.o obj-$(CONFIG_BT_ATH3K) += ath3k.o obj-$(CONFIG_BT_MRVL) += btmrvl.o obj-$(CONFIG_BT_MRVL_SDIO) += btmrvl_sdio.o -obj-$(CONFIG_BT_WILINK) += btwilink.o obj-$(CONFIG_BT_MTKSDIO) += btmtksdio.o obj-$(CONFIG_BT_MTKUART) += btmtkuart.o obj-$(CONFIG_BT_QCOMSMD) += btqcomsmd.o diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 2d2e6d862068..8e05706fe5d9 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -23,6 +23,7 @@ #define BDADDR_BCM43430A0 (&(bdaddr_t) {{0xac, 0x1f, 0x12, 0xa0, 0x43, 0x43}}) #define BDADDR_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}}) #define BDADDR_BCM4330B1 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb1, 0x30, 0x43}}) +#define BDADDR_BCM4334B0 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb0, 0x34, 0x43}}) #define BDADDR_BCM4345C5 (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0xc5, 0x45, 0x43}}) #define BDADDR_BCM43341B (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0x1b, 0x34, 0x43}}) @@ -74,6 +75,7 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) !bacmp(&bda->bdaddr, BDADDR_BCM2076B1) || !bacmp(&bda->bdaddr, BDADDR_BCM4324B3) || !bacmp(&bda->bdaddr, BDADDR_BCM4330B1) || + !bacmp(&bda->bdaddr, BDADDR_BCM4334B0) || !bacmp(&bda->bdaddr, BDADDR_BCM4345C5) || !bacmp(&bda->bdaddr, BDADDR_BCM43430A0) || !bacmp(&bda->bdaddr, BDADDR_BCM43341B)) { @@ -326,6 +328,7 @@ struct bcm_subver_table { static const struct bcm_subver_table bcm_uart_subver_table[] = { { 0x4103, "BCM4330B1" }, /* 002.001.003 */ + { 0x410d, "BCM4334B0" }, /* 002.001.013 */ { 0x410e, "BCM43341B0" }, /* 002.001.014 */ { 0x4204, "BCM2076B1" }, /* 002.002.004 */ { 0x4406, "BCM4324B3" }, /* 002.004.006 */ @@ -339,6 +342,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = { { 0x220e, "BCM20702A1" }, /* 001.002.014 */ { 0x4217, "BCM4329B1" }, /* 002.002.023 */ { 0x6106, "BCM4359C0" }, /* 003.001.006 */ + { 0x4106, "BCM4335A0" }, /* 002.001.006 */ { } }; @@ -440,6 +444,12 @@ int btbcm_finalize(struct hci_dev *hdev) set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); + /* Some devices ship with the controller default address. + * Allow the bootloader to set a valid address through the + * device tree. + */ + set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); + return 0; } EXPORT_SYMBOL_GPL(btbcm_finalize); diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index bb99c8653aab..62e781a18bf0 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -709,6 +709,51 @@ done: } EXPORT_SYMBOL_GPL(btintel_download_firmware); +void btintel_reset_to_bootloader(struct hci_dev *hdev) +{ + struct intel_reset params; + struct sk_buff *skb; + + /* Send Intel Reset command. This will result in + * re-enumeration of BT controller. + * + * Intel Reset parameter description: + * reset_type : 0x00 (Soft reset), + * 0x01 (Hard reset) + * patch_enable : 0x00 (Do not enable), + * 0x01 (Enable) + * ddc_reload : 0x00 (Do not reload), + * 0x01 (Reload) + * boot_option: 0x00 (Current image), + * 0x01 (Specified boot address) + * boot_param: Boot address + * + */ + params.reset_type = 0x01; + params.patch_enable = 0x01; + params.ddc_reload = 0x01; + params.boot_option = 0x00; + params.boot_param = cpu_to_le32(0x00000000); + + skb = __hci_cmd_sync(hdev, 0xfc01, sizeof(params), + ¶ms, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + bt_dev_err(hdev, "FW download error recovery failed (%ld)", + PTR_ERR(skb)); + return; + } + bt_dev_info(hdev, "Intel reset sent to retry FW download"); + kfree_skb(skb); + + /* Current Intel BT controllers(ThP/JfP) hold the USB reset + * lines for 2ms when it receives Intel Reset in bootloader mode. + * Whereas, the upcoming Intel BT controllers will hold USB reset + * for 150ms. To keep the delay generic, 150ms is chosen here. + */ + msleep(150); +} +EXPORT_SYMBOL_GPL(btintel_reset_to_bootloader); + MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION); MODULE_VERSION(VERSION); diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h index 3d846190f2bf..a69ea8a87b9b 100644 --- a/drivers/bluetooth/btintel.h +++ b/drivers/bluetooth/btintel.h @@ -87,6 +87,7 @@ int btintel_read_boot_params(struct hci_dev *hdev, struct intel_boot_params *params); int btintel_download_firmware(struct hci_dev *dev, const struct firmware *fw, u32 *boot_param); +void btintel_reset_to_bootloader(struct hci_dev *hdev); #else static inline int btintel_check_bdaddr(struct hci_dev *hdev) @@ -181,4 +182,8 @@ static inline int btintel_download_firmware(struct hci_dev *dev, { return -EOPNOTSUPP; } + +static inline void btintel_reset_to_bootloader(struct hci_dev *hdev) +{ +} #endif diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index 813338288453..519788c442ca 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -57,6 +57,7 @@ static const struct sdio_device_id btmtksdio_table[] = { .driver_data = (kernel_ulong_t)&mt7668_data }, { } /* Terminating entry */ }; +MODULE_DEVICE_TABLE(sdio, btmtksdio_table); #define MTK_REG_CHLPCR 0x4 /* W1S */ #define C_INT_EN_SET BIT(0) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 8cc21ad7cf29..ec69e5dd7bd3 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -14,19 +14,33 @@ #define VERSION "0.1" -int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version) +int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, + enum qca_btsoc_type soc_type) { struct sk_buff *skb; struct edl_event_hdr *edl; - struct rome_version *ver; + struct qca_btsoc_version *ver; char cmd; int err = 0; + u8 event_type = HCI_EV_VENDOR; + u8 rlen = sizeof(*edl) + sizeof(*ver); + u8 rtype = EDL_APP_VER_RES_EVT; bt_dev_dbg(hdev, "QCA Version Request"); + /* Unlike other SoC's sending version command response as payload to + * VSE event. WCN3991 sends version command response as a payload to + * command complete event. + */ + if (soc_type == QCA_WCN3991) { + event_type = 0; + rlen += 1; + rtype = EDL_PATCH_VER_REQ_CMD; + } + cmd = EDL_PATCH_VER_REQ_CMD; skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN, - &cmd, HCI_EV_VENDOR, HCI_INIT_TIMEOUT); + &cmd, event_type, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { err = PTR_ERR(skb); bt_dev_err(hdev, "Reading QCA version information failed (%d)", @@ -34,7 +48,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version) return err; } - if (skb->len != sizeof(*edl) + sizeof(*ver)) { + if (skb->len != rlen) { bt_dev_err(hdev, "QCA Version size mismatch len %d", skb->len); err = -EILSEQ; goto out; @@ -48,18 +62,21 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version) } if (edl->cresp != EDL_CMD_REQ_RES_EVT || - edl->rtype != EDL_APP_VER_RES_EVT) { + edl->rtype != rtype) { bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp, edl->rtype); err = -EIO; goto out; } - ver = (struct rome_version *)(edl->data); + if (soc_type == QCA_WCN3991) + memmove(&edl->data, &edl->data[1], sizeof(*ver)); + + ver = (struct qca_btsoc_version *)(edl->data); BT_DBG("%s: Product:0x%08x", hdev->name, le32_to_cpu(ver->product_id)); BT_DBG("%s: Patch :0x%08x", hdev->name, le16_to_cpu(ver->patch_ver)); - BT_DBG("%s: ROM :0x%08x", hdev->name, le16_to_cpu(ver->rome_ver)); + BT_DBG("%s: ROM :0x%08x", hdev->name, le16_to_cpu(ver->rom_ver)); BT_DBG("%s: SOC :0x%08x", hdev->name, le32_to_cpu(ver->soc_id)); /* QCA chipset version can be decided by patch and SoC @@ -67,7 +84,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version) * and lower 2 bytes from patch will be used. */ *soc_version = (le32_to_cpu(ver->soc_id) << 16) | - (le16_to_cpu(ver->rome_ver) & 0x0000ffff); + (le16_to_cpu(ver->rom_ver) & 0x0000ffff); if (*soc_version == 0) err = -EILSEQ; @@ -121,7 +138,7 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) } EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); -static void qca_tlv_check_data(struct rome_config *config, +static void qca_tlv_check_data(struct qca_fw_config *config, const struct firmware *fw) { const u8 *data; @@ -140,8 +157,8 @@ static void qca_tlv_check_data(struct rome_config *config, BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff); BT_DBG("Length\t\t : %d bytes", length); - config->dnld_mode = ROME_SKIP_EVT_NONE; - config->dnld_type = ROME_SKIP_EVT_NONE; + config->dnld_mode = QCA_SKIP_EVT_NONE; + config->dnld_type = QCA_SKIP_EVT_NONE; switch (config->type) { case TLV_TYPE_PATCH: @@ -223,31 +240,45 @@ static void qca_tlv_check_data(struct rome_config *config, } static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, - const u8 *data, enum rome_tlv_dnld_mode mode) + const u8 *data, enum qca_tlv_dnld_mode mode, + enum qca_btsoc_type soc_type) { struct sk_buff *skb; struct edl_event_hdr *edl; struct tlv_seg_resp *tlv_resp; u8 cmd[MAX_SIZE_PER_TLV_SEGMENT + 2]; int err = 0; + u8 event_type = HCI_EV_VENDOR; + u8 rlen = (sizeof(*edl) + sizeof(*tlv_resp)); + u8 rtype = EDL_TVL_DNLD_RES_EVT; cmd[0] = EDL_PATCH_TLV_REQ_CMD; cmd[1] = seg_size; memcpy(cmd + 2, data, seg_size); - if (mode == ROME_SKIP_EVT_VSE_CC || mode == ROME_SKIP_EVT_VSE) + if (mode == QCA_SKIP_EVT_VSE_CC || mode == QCA_SKIP_EVT_VSE) return __hci_cmd_send(hdev, EDL_PATCH_CMD_OPCODE, seg_size + 2, cmd); + /* Unlike other SoC's sending version command response as payload to + * VSE event. WCN3991 sends version command response as a payload to + * command complete event. + */ + if (soc_type == QCA_WCN3991) { + event_type = 0; + rlen = sizeof(*edl); + rtype = EDL_PATCH_TLV_REQ_CMD; + } + skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, seg_size + 2, cmd, - HCI_EV_VENDOR, HCI_INIT_TIMEOUT); + event_type, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { err = PTR_ERR(skb); bt_dev_err(hdev, "QCA Failed to send TLV segment (%d)", err); return err; } - if (skb->len != sizeof(*edl) + sizeof(*tlv_resp)) { + if (skb->len != rlen) { bt_dev_err(hdev, "QCA TLV response size mismatch"); err = -EILSEQ; goto out; @@ -260,13 +291,19 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, goto out; } - tlv_resp = (struct tlv_seg_resp *)(edl->data); + if (edl->cresp != EDL_CMD_REQ_RES_EVT || edl->rtype != rtype) { + bt_dev_err(hdev, "QCA TLV with error stat 0x%x rtype 0x%x", + edl->cresp, edl->rtype); + err = -EIO; + } - if (edl->cresp != EDL_CMD_REQ_RES_EVT || - edl->rtype != EDL_TVL_DNLD_RES_EVT || tlv_resp->result != 0x00) { + if (soc_type == QCA_WCN3991) + goto out; + + tlv_resp = (struct tlv_seg_resp *)(edl->data); + if (tlv_resp->result) { bt_dev_err(hdev, "QCA TLV with error stat 0x%x rtype 0x%x (0x%x)", edl->cresp, edl->rtype, tlv_resp->result); - err = -EIO; } out: @@ -301,7 +338,8 @@ static int qca_inject_cmd_complete_event(struct hci_dev *hdev) } static int qca_download_firmware(struct hci_dev *hdev, - struct rome_config *config) + struct qca_fw_config *config, + enum qca_btsoc_type soc_type) { const struct firmware *fw; const u8 *segment; @@ -328,10 +366,10 @@ static int qca_download_firmware(struct hci_dev *hdev, remain -= segsize; /* The last segment is always acked regardless download mode */ if (!remain || segsize < MAX_SIZE_PER_TLV_SEGMENT) - config->dnld_mode = ROME_SKIP_EVT_NONE; + config->dnld_mode = QCA_SKIP_EVT_NONE; ret = qca_tlv_send_segment(hdev, segsize, segment, - config->dnld_mode); + config->dnld_mode, soc_type); if (ret) goto out; @@ -344,8 +382,8 @@ static int qca_download_firmware(struct hci_dev *hdev, * decrease the BT in initialization time. Here we will inject a command * complete event to avoid a command timeout error message. */ - if (config->dnld_type == ROME_SKIP_EVT_VSE_CC || - config->dnld_type == ROME_SKIP_EVT_VSE) + if (config->dnld_type == QCA_SKIP_EVT_VSE_CC || + config->dnld_type == QCA_SKIP_EVT_VSE) ret = qca_inject_cmd_complete_event(hdev); out: @@ -382,7 +420,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, enum qca_btsoc_type soc_type, u32 soc_ver, const char *firmware_name) { - struct rome_config config; + struct qca_fw_config config; int err; u8 rom_ver = 0; @@ -405,7 +443,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/rampatch_%08x.bin", soc_ver); } - err = qca_download_firmware(hdev, &config); + err = qca_download_firmware(hdev, &config, soc_type); if (err < 0) { bt_dev_err(hdev, "QCA Failed to download patch (%d)", err); return err; @@ -426,7 +464,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin", soc_ver); - err = qca_download_firmware(hdev, &config); + err = qca_download_firmware(hdev, &config, soc_type); if (err < 0) { bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err); return err; diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index 69c5315a65fd..f5795b1a3779 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -56,24 +56,24 @@ enum qca_baudrate { QCA_BAUDRATE_RESERVED }; -enum rome_tlv_dnld_mode { - ROME_SKIP_EVT_NONE, - ROME_SKIP_EVT_VSE, - ROME_SKIP_EVT_CC, - ROME_SKIP_EVT_VSE_CC +enum qca_tlv_dnld_mode { + QCA_SKIP_EVT_NONE, + QCA_SKIP_EVT_VSE, + QCA_SKIP_EVT_CC, + QCA_SKIP_EVT_VSE_CC }; -enum rome_tlv_type { +enum qca_tlv_type { TLV_TYPE_PATCH = 1, TLV_TYPE_NVM }; -struct rome_config { +struct qca_fw_config { u8 type; char fwname[64]; uint8_t user_baud_rate; - enum rome_tlv_dnld_mode dnld_mode; - enum rome_tlv_dnld_mode dnld_type; + enum qca_tlv_dnld_mode dnld_mode; + enum qca_tlv_dnld_mode dnld_type; }; struct edl_event_hdr { @@ -82,10 +82,10 @@ struct edl_event_hdr { __u8 data[0]; } __packed; -struct rome_version { +struct qca_btsoc_version { __le32 product_id; __le16 patch_ver; - __le16 rome_ver; + __le16 rom_ver; __le32 soc_id; } __packed; @@ -125,6 +125,7 @@ enum qca_btsoc_type { QCA_AR3002, QCA_ROME, QCA_WCN3990, + QCA_WCN3991, QCA_WCN3998, }; @@ -134,12 +135,14 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr); int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, enum qca_btsoc_type soc_type, u32 soc_ver, const char *firmware_name); -int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version); +int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, + enum qca_btsoc_type); int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); int qca_send_pre_shutdown_cmd(struct hci_dev *hdev); static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) { - return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3998; + return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3991 || + soc_type == QCA_WCN3998; } #else @@ -155,7 +158,8 @@ static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, return -EOPNOTSUPP; } -static inline int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version) +static inline int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, + enum qca_btsoc_type) { return -EOPNOTSUPP; } diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index bf3c02be6930..f838537f9f89 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -418,7 +418,7 @@ static int rtl_download_firmware(struct hci_dev *hdev, if (IS_ERR(skb)) { rtl_dev_err(hdev, "download fw command failed (%ld)", PTR_ERR(skb)); - ret = -PTR_ERR(skb); + ret = PTR_ERR(skb); goto out; } @@ -778,7 +778,7 @@ int btrtl_get_uart_settings(struct hci_dev *hdev, rtl_dev_dbg(hdev, "skipping config entry 0x%x (len %u)", le16_to_cpu(entry->offset), entry->len); break; - }; + } i += sizeof(*entry) + entry->len; } diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index a9c35ebb30f8..70e385987d41 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1200,7 +1200,7 @@ static int btusb_open(struct hci_dev *hdev) if (data->setup_on_usb) { err = data->setup_on_usb(hdev); if (err < 0) - return err; + goto setup_fail; } data->intf->needs_remote_wakeup = 1; @@ -1239,6 +1239,7 @@ done: failed: clear_bit(BTUSB_INTR_RUNNING, &data->flags); +setup_fail: usb_autopm_put_interface(data->intf); return err; } @@ -2182,8 +2183,11 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) * loaded. */ err = btintel_read_version(hdev, &ver); - if (err) + if (err) { + bt_dev_err(hdev, "Intel Read version failed (%d)", err); + btintel_reset_to_bootloader(hdev); return err; + } /* The hardware platform number has a fixed value of 0x37 and * for now only accept this single value. @@ -2326,9 +2330,13 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) /* Start firmware downloading and get boot parameter */ err = btintel_download_firmware(hdev, fw, &boot_param); - if (err < 0) + if (err < 0) { + /* When FW download fails, send Intel Reset to retry + * FW download. + */ + btintel_reset_to_bootloader(hdev); goto done; - + } set_bit(BTUSB_FIRMWARE_LOADED, &data->flags); bt_dev_info(hdev, "Waiting for firmware download to complete"); @@ -2355,6 +2363,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) if (err) { bt_dev_err(hdev, "Firmware loading timeout"); err = -ETIMEDOUT; + btintel_reset_to_bootloader(hdev); goto done; } @@ -2381,8 +2390,11 @@ done: set_bit(BTUSB_BOOTING, &data->flags); err = btintel_send_intel_reset(hdev, boot_param); - if (err) + if (err) { + bt_dev_err(hdev, "Intel Soft Reset failed (%d)", err); + btintel_reset_to_bootloader(hdev); return err; + } /* The bootloader will not indicate when the device is ready. This * is done by the operational firmware sending bootup notification. @@ -2404,6 +2416,7 @@ done: if (err) { bt_dev_err(hdev, "Device boot timeout"); + btintel_reset_to_bootloader(hdev); return -ETIMEDOUT; } @@ -2432,6 +2445,13 @@ done: */ btintel_set_event_mask(hdev, false); + /* Read the Intel version information after loading the FW */ + err = btintel_read_version(hdev, &ver); + if (err) + return err; + + btintel_version_info(hdev, &ver); + return 0; } @@ -2489,8 +2509,6 @@ static int btusb_shutdown_intel_new(struct hci_dev *hdev) return 0; } -#ifdef CONFIG_BT_HCIBTUSB_MTK - #define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin" #define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin" @@ -3051,7 +3069,6 @@ static int btusb_mtk_shutdown(struct hci_dev *hdev) MODULE_FIRMWARE(FIRMWARE_MT7663); MODULE_FIRMWARE(FIRMWARE_MT7668); -#endif #ifdef CONFIG_PM /* Configure an out-of-band gpio as wake-up pin, if specified in device tree */ @@ -3411,7 +3428,6 @@ static int btusb_setup_qca(struct hci_dev *hdev) return 0; } -#ifdef CONFIG_BT_HCIBTUSB_BCM static inline int __set_diag_interface(struct hci_dev *hdev) { struct btusb_data *data = hci_get_drvdata(hdev); @@ -3498,7 +3514,6 @@ static int btusb_bcm_set_diag(struct hci_dev *hdev, bool enable) return submit_or_queue_tx_urb(hdev, urb); } -#endif #ifdef CONFIG_PM static irqreturn_t btusb_oob_wake_handler(int irq, void *priv) @@ -3724,8 +3739,8 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_BCM92035) hdev->setup = btusb_setup_bcm92035; -#ifdef CONFIG_BT_HCIBTUSB_BCM - if (id->driver_info & BTUSB_BCM_PATCHRAM) { + if (IS_ENABLED(CONFIG_BT_HCIBTUSB_BCM) && + (id->driver_info & BTUSB_BCM_PATCHRAM)) { hdev->manufacturer = 15; hdev->setup = btbcm_setup_patchram; hdev->set_diag = btusb_bcm_set_diag; @@ -3735,7 +3750,8 @@ static int btusb_probe(struct usb_interface *intf, data->diag = usb_ifnum_to_if(data->udev, ifnum_base + 2); } - if (id->driver_info & BTUSB_BCM_APPLE) { + if (IS_ENABLED(CONFIG_BT_HCIBTUSB_BCM) && + (id->driver_info & BTUSB_BCM_APPLE)) { hdev->manufacturer = 15; hdev->setup = btbcm_setup_apple; hdev->set_diag = btusb_bcm_set_diag; @@ -3743,7 +3759,6 @@ static int btusb_probe(struct usb_interface *intf, /* Broadcom LM_DIAG Interface numbers are hardcoded */ data->diag = usb_ifnum_to_if(data->udev, ifnum_base + 2); } -#endif if (id->driver_info & BTUSB_INTEL) { hdev->manufacturer = 2; @@ -3774,14 +3789,13 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_MARVELL) hdev->set_bdaddr = btusb_set_bdaddr_marvell; -#ifdef CONFIG_BT_HCIBTUSB_MTK - if (id->driver_info & BTUSB_MEDIATEK) { + if (IS_ENABLED(CONFIG_BT_HCIBTUSB_MTK) && + (id->driver_info & BTUSB_MEDIATEK)) { hdev->setup = btusb_mtk_setup; hdev->shutdown = btusb_mtk_shutdown; hdev->manufacturer = 70; set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); } -#endif if (id->driver_info & BTUSB_SWAVE) { set_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks); @@ -3807,8 +3821,8 @@ static int btusb_probe(struct usb_interface *intf, btusb_check_needs_reset_resume(intf); } -#ifdef CONFIG_BT_HCIBTUSB_RTL - if (id->driver_info & BTUSB_REALTEK) { + if (IS_ENABLED(CONFIG_BT_HCIBTUSB_RTL) && + (id->driver_info & BTUSB_REALTEK)) { hdev->setup = btrtl_setup_realtek; hdev->shutdown = btrtl_shutdown_realtek; hdev->cmd_timeout = btusb_rtl_cmd_timeout; @@ -3819,7 +3833,6 @@ static int btusb_probe(struct usb_interface *intf, */ set_bit(BTUSB_WAKEUP_DISABLE, &data->flags); } -#endif if (id->driver_info & BTUSB_AMP) { /* AMP controllers do not support SCO packets */ @@ -3887,15 +3900,13 @@ static int btusb_probe(struct usb_interface *intf, goto out_free_dev; } -#ifdef CONFIG_BT_HCIBTUSB_BCM - if (data->diag) { + if (IS_ENABLED(CONFIG_BT_HCIBTUSB_BCM) && data->diag) { if (!usb_driver_claim_interface(&btusb_driver, data->diag, data)) __set_diag_interface(hdev); else data->diag = NULL; } -#endif if (enable_autosuspend) usb_enable_autosuspend(data->udev); diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c deleted file mode 100644 index e55f06e4270f..000000000000 --- a/drivers/bluetooth/btwilink.c +++ /dev/null @@ -1,337 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Texas Instrument's Bluetooth Driver For Shared Transport. - * - * Bluetooth Driver acts as interface between HCI core and - * TI Shared Transport Layer. - * - * Copyright (C) 2009-2010 Texas Instruments - * Author: Raja Mani <raja_mani@ti.com> - * Pavan Savoy <pavan_savoy@ti.com> - */ - -#include <linux/platform_device.h> -#include <net/bluetooth/bluetooth.h> -#include <net/bluetooth/hci_core.h> -#include <net/bluetooth/hci.h> - -#include <linux/ti_wilink_st.h> -#include <linux/module.h> - -/* Bluetooth Driver Version */ -#define VERSION "1.0" -#define MAX_BT_CHNL_IDS 3 - -/* Number of seconds to wait for registration completion - * when ST returns PENDING status. - */ -#define BT_REGISTER_TIMEOUT 6000 /* 6 sec */ - -/** - * struct ti_st - driver operation structure - * @hdev: hci device pointer which binds to bt driver - * @reg_status: ST registration callback status - * @st_write: write function provided by the ST driver - * to be used by the driver during send_frame. - * @wait_reg_completion - completion sync between ti_st_open - * and st_reg_completion_cb. - */ -struct ti_st { - struct hci_dev *hdev; - int reg_status; - long (*st_write) (struct sk_buff *); - struct completion wait_reg_completion; -}; - -/* Increments HCI counters based on pocket ID (cmd,acl,sco) */ -static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type) -{ - struct hci_dev *hdev = hst->hdev; - - /* Update HCI stat counters */ - switch (pkt_type) { - case HCI_COMMAND_PKT: - hdev->stat.cmd_tx++; - break; - - case HCI_ACLDATA_PKT: - hdev->stat.acl_tx++; - break; - - case HCI_SCODATA_PKT: - hdev->stat.sco_tx++; - break; - } -} - -/* ------- Interfaces to Shared Transport ------ */ - -/* Called by ST layer to indicate protocol registration completion - * status.ti_st_open() function will wait for signal from this - * API when st_register() function returns ST_PENDING. - */ -static void st_reg_completion_cb(void *priv_data, int data) -{ - struct ti_st *lhst = priv_data; - - /* Save registration status for use in ti_st_open() */ - lhst->reg_status = data; - /* complete the wait in ti_st_open() */ - complete(&lhst->wait_reg_completion); -} - -/* Called by Shared Transport layer when receive data is available */ -static long st_receive(void *priv_data, struct sk_buff *skb) -{ - struct ti_st *lhst = priv_data; - int err; - - if (!skb) - return -EFAULT; - - if (!lhst) { - kfree_skb(skb); - return -EFAULT; - } - - /* Forward skb to HCI core layer */ - err = hci_recv_frame(lhst->hdev, skb); - if (err < 0) { - BT_ERR("Unable to push skb to HCI core(%d)", err); - return err; - } - - lhst->hdev->stat.byte_rx += skb->len; - - return 0; -} - -/* ------- Interfaces to HCI layer ------ */ -/* protocol structure registered with shared transport */ -static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = { - { - .chnl_id = HCI_EVENT_PKT, /* HCI Events */ - .hdr_len = sizeof(struct hci_event_hdr), - .offset_len_in_hdr = offsetof(struct hci_event_hdr, plen), - .len_size = 1, /* sizeof(plen) in struct hci_event_hdr */ - .reserve = 8, - }, - { - .chnl_id = HCI_ACLDATA_PKT, /* ACL */ - .hdr_len = sizeof(struct hci_acl_hdr), - .offset_len_in_hdr = offsetof(struct hci_acl_hdr, dlen), - .len_size = 2, /* sizeof(dlen) in struct hci_acl_hdr */ - .reserve = 8, - }, - { - .chnl_id = HCI_SCODATA_PKT, /* SCO */ - .hdr_len = sizeof(struct hci_sco_hdr), - .offset_len_in_hdr = offsetof(struct hci_sco_hdr, dlen), - .len_size = 1, /* sizeof(dlen) in struct hci_sco_hdr */ - .reserve = 8, - }, -}; - -/* Called from HCI core to initialize the device */ -static int ti_st_open(struct hci_dev *hdev) -{ - unsigned long timeleft; - struct ti_st *hst; - int err, i; - - BT_DBG("%s %p", hdev->name, hdev); - - /* provide contexts for callbacks from ST */ - hst = hci_get_drvdata(hdev); - - for (i = 0; i < MAX_BT_CHNL_IDS; i++) { - ti_st_proto[i].priv_data = hst; - ti_st_proto[i].max_frame_size = HCI_MAX_FRAME_SIZE; - ti_st_proto[i].recv = st_receive; - ti_st_proto[i].reg_complete_cb = st_reg_completion_cb; - - /* Prepare wait-for-completion handler */ - init_completion(&hst->wait_reg_completion); - /* Reset ST registration callback status flag, - * this value will be updated in - * st_reg_completion_cb() - * function whenever it called from ST driver. - */ - hst->reg_status = -EINPROGRESS; - - err = st_register(&ti_st_proto[i]); - if (!err) - goto done; - - if (err != -EINPROGRESS) { - BT_ERR("st_register failed %d", err); - return err; - } - - /* ST is busy with either protocol - * registration or firmware download. - */ - BT_DBG("waiting for registration " - "completion signal from ST"); - timeleft = wait_for_completion_timeout - (&hst->wait_reg_completion, - msecs_to_jiffies(BT_REGISTER_TIMEOUT)); - if (!timeleft) { - BT_ERR("Timeout(%d sec),didn't get reg " - "completion signal from ST", - BT_REGISTER_TIMEOUT / 1000); - return -ETIMEDOUT; - } - - /* Is ST registration callback - * called with ERROR status? - */ - if (hst->reg_status != 0) { - BT_ERR("ST registration completed with invalid " - "status %d", hst->reg_status); - return -EAGAIN; - } - -done: - hst->st_write = ti_st_proto[i].write; - if (!hst->st_write) { - BT_ERR("undefined ST write function"); - for (i = 0; i < MAX_BT_CHNL_IDS; i++) { - /* Undo registration with ST */ - err = st_unregister(&ti_st_proto[i]); - if (err) - BT_ERR("st_unregister() failed with " - "error %d", err); - hst->st_write = NULL; - } - return -EIO; - } - } - return 0; -} - -/* Close device */ -static int ti_st_close(struct hci_dev *hdev) -{ - int err, i; - struct ti_st *hst = hci_get_drvdata(hdev); - - for (i = MAX_BT_CHNL_IDS-1; i >= 0; i--) { - err = st_unregister(&ti_st_proto[i]); - if (err) - BT_ERR("st_unregister(%d) failed with error %d", - ti_st_proto[i].chnl_id, err); - } - - hst->st_write = NULL; - - return err; -} - -static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct ti_st *hst; - long len; - int pkt_type; - - hst = hci_get_drvdata(hdev); - - /* Prepend skb with frame type */ - memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); - - BT_DBG("%s: type %d len %d", hdev->name, hci_skb_pkt_type(skb), - skb->len); - - /* Insert skb to shared transport layer's transmit queue. - * Freeing skb memory is taken care in shared transport layer, - * so don't free skb memory here. - */ - pkt_type = hci_skb_pkt_type(skb); - len = hst->st_write(skb); - if (len < 0) { - BT_ERR("ST write failed (%ld)", len); |