diff options
Diffstat (limited to 'drivers/bluetooth')
| -rw-r--r-- | drivers/bluetooth/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/bluetooth/bpa10x.c | 4 | ||||
| -rw-r--r-- | drivers/bluetooth/btbcm.c | 4 | ||||
| -rw-r--r-- | drivers/bluetooth/btintel_pcie.c | 186 | ||||
| -rw-r--r-- | drivers/bluetooth/btintel_pcie.h | 4 | ||||
| -rw-r--r-- | drivers/bluetooth/btmtksdio.c | 13 | ||||
| -rw-r--r-- | drivers/bluetooth/btmtkuart.c | 4 | ||||
| -rw-r--r-- | drivers/bluetooth/btnxpuart.c | 4 | ||||
| -rw-r--r-- | drivers/bluetooth/btrtl.c | 44 | ||||
| -rw-r--r-- | drivers/bluetooth/btusb.c | 99 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_ag6xx.c | 2 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_aml.c | 2 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_ath.c | 2 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_bcm.c | 8 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_h4.c | 6 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_h5.c | 53 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_intel.c | 5 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_ll.c | 2 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_mrvl.c | 6 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_nokia.c | 4 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_qca.c | 2 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_uart.h | 2 |
22 files changed, 363 insertions, 94 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 7df69ccb6600..c5d45cf91f88 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -188,6 +188,7 @@ config BT_HCIUART_3WIRE bool "Three-wire UART (H5) protocol support" depends on BT_HCIUART depends on BT_HCIUART_SERDEV + select CRC_CCITT help The HCI Three-wire UART Transport Layer makes it possible to user the Bluetooth HCI over a serial port interface. The HCI diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index b7ba667a3d09..e305d04aac9d 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c @@ -41,6 +41,7 @@ struct bpa10x_data { struct usb_anchor rx_anchor; struct sk_buff *rx_skb[2]; + struct hci_uart hu; }; static void bpa10x_tx_complete(struct urb *urb) @@ -96,7 +97,7 @@ static void bpa10x_rx_complete(struct urb *urb) if (urb->status == 0) { bool idx = usb_pipebulk(urb->pipe); - data->rx_skb[idx] = h4_recv_buf(hdev, data->rx_skb[idx], + data->rx_skb[idx] = h4_recv_buf(&data->hu, data->rx_skb[idx], urb->transfer_buffer, urb->actual_length, bpa10x_recv_pkts, @@ -388,6 +389,7 @@ static int bpa10x_probe(struct usb_interface *intf, hci_set_drvdata(hdev, data); data->hdev = hdev; + data->hu.hdev = hdev; SET_HCIDEV_DEV(hdev, &intf->dev); diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 3a3a56ddbb06..d33cc70eec66 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -642,7 +642,9 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done, bool use_autobaud snprintf(postfix, sizeof(postfix), "-%4.4x-%4.4x", vid, pid); } - fw_name = kmalloc(BCM_FW_NAME_COUNT_MAX * BCM_FW_NAME_LEN, GFP_KERNEL); + fw_name = kmalloc_array(BCM_FW_NAME_COUNT_MAX, + sizeof(*fw_name), + GFP_KERNEL); if (!fw_name) return -ENOMEM; diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c index 6d3963bd56a9..2936b535479f 100644 --- a/drivers/bluetooth/btintel_pcie.c +++ b/drivers/bluetooth/btintel_pcie.c @@ -19,6 +19,7 @@ #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> +#include <net/bluetooth/hci_drv.h> #include "btintel.h" #include "btintel_pcie.h" @@ -825,6 +826,11 @@ static inline bool btintel_pcie_in_d0(struct btintel_pcie_data *data) return !(data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY); } +static inline bool btintel_pcie_in_device_halt(struct btintel_pcie_data *data) +{ + return data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_HALTED; +} + static void btintel_pcie_wr_sleep_cntrl(struct btintel_pcie_data *data, u32 dxstate) { @@ -1467,11 +1473,6 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id) if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP1) btintel_pcie_msix_gp1_handler(data); - /* This interrupt is triggered by the firmware after updating - * boot_stage register and image_response register - */ - if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0) - btintel_pcie_msix_gp0_handler(data); /* For TX */ if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) { @@ -1487,6 +1488,12 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id) btintel_pcie_msix_tx_handle(data); } + /* This interrupt is triggered by the firmware after updating + * boot_stage register and image_response register + */ + if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0) + btintel_pcie_msix_gp0_handler(data); + /* * Before sending the interrupt the HW disables it to prevent a nested * interrupt. This is done by writing 1 to the corresponding bit in @@ -2354,6 +2361,63 @@ static bool btintel_pcie_wakeup(struct hci_dev *hdev) return device_may_wakeup(&data->pdev->dev); } +static const struct { + u16 opcode; + const char *desc; +} btintel_pcie_hci_drv_supported_commands[] = { + /* Common commands */ + { HCI_DRV_OP_READ_INFO, "Read Info" }, +}; + +static int btintel_pcie_hci_drv_read_info(struct hci_dev *hdev, void *data, + u16 data_len) +{ + struct hci_drv_rp_read_info *rp; + size_t rp_size; + int err, i; + u16 opcode, num_supported_commands = + ARRAY_SIZE(btintel_pcie_hci_drv_supported_commands); + + rp_size = sizeof(*rp) + num_supported_commands * 2; + + rp = kmalloc(rp_size, GFP_KERNEL); + if (!rp) + return -ENOMEM; + + strscpy_pad(rp->driver_name, KBUILD_MODNAME); + + rp->num_supported_commands = cpu_to_le16(num_supported_commands); + for (i = 0; i < num_supported_commands; i++) { + opcode = btintel_pcie_hci_drv_supported_commands[i].opcode; + bt_dev_dbg(hdev, + "Supported HCI Drv command (0x%02x|0x%04x): %s", + hci_opcode_ogf(opcode), + hci_opcode_ocf(opcode), + btintel_pcie_hci_drv_supported_commands[i].desc); + rp->supported_commands[i] = cpu_to_le16(opcode); + } + + err = hci_drv_cmd_complete(hdev, HCI_DRV_OP_READ_INFO, + HCI_DRV_STATUS_SUCCESS, + rp, rp_size); + + kfree(rp); + return err; +} + +static const struct hci_drv_handler btintel_pcie_hci_drv_common_handlers[] = { + { btintel_pcie_hci_drv_read_info, HCI_DRV_READ_INFO_SIZE }, +}; + +static const struct hci_drv_handler btintel_pcie_hci_drv_specific_handlers[] = {}; + +static struct hci_drv btintel_pcie_hci_drv = { + .common_handler_count = ARRAY_SIZE(btintel_pcie_hci_drv_common_handlers), + .common_handlers = btintel_pcie_hci_drv_common_handlers, + .specific_handler_count = ARRAY_SIZE(btintel_pcie_hci_drv_specific_handlers), + .specific_handlers = btintel_pcie_hci_drv_specific_handlers, +}; + static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) { int err; @@ -2380,6 +2444,7 @@ static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) hdev->set_bdaddr = btintel_set_bdaddr; hdev->reset = btintel_pcie_reset; hdev->wakeup = btintel_pcie_wakeup; + hdev->hci_drv = &btintel_pcie_hci_drv; err = hci_register_dev(hdev); if (err < 0) { @@ -2518,6 +2583,48 @@ static void btintel_pcie_coredump(struct device *dev) } #endif +static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate) +{ + int retry = 0, status; + u32 dx_intr_timeout_ms = 200; + + do { + data->gp0_received = false; + + btintel_pcie_wr_sleep_cntrl(data, dxstate); + + status = wait_event_timeout(data->gp0_wait_q, data->gp0_received, + msecs_to_jiffies(dx_intr_timeout_ms)); + + if (status) + return 0; + + bt_dev_warn(data->hdev, + "Timeout (%u ms) on alive interrupt for D%d entry, retry count %d", + dx_intr_timeout_ms, dxstate, retry); + + /* clear gp0 cause */ + btintel_pcie_clr_reg_bits(data, + BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES, + BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0); + + /* A hardware bug may cause the alive interrupt to be missed. + * Check if the controller reached the expected state and retry + * the operation only if it hasn't. + */ + if (dxstate == BTINTEL_PCIE_STATE_D0) { + if (btintel_pcie_in_d0(data)) + return 0; + } else { + if (btintel_pcie_in_d3(data)) + return 0; + } + + } while (++retry < BTINTEL_PCIE_DX_TRANSITION_MAX_RETRIES); + + return -EBUSY; +} + static int btintel_pcie_suspend_late(struct device *dev, pm_message_t mesg) { struct pci_dev *pdev = to_pci_dev(dev); @@ -2531,26 +2638,20 @@ static int btintel_pcie_suspend_late(struct device *dev, pm_message_t mesg) dxstate = (mesg.event == PM_EVENT_SUSPEND ? BTINTEL_PCIE_STATE_D3_HOT : BTINTEL_PCIE_STATE_D3_COLD); - data->gp0_received = false; + data->pm_sx_event = mesg.event; start = ktime_get(); /* Refer: 6.4.11.7 -> Platform power management */ - btintel_pcie_wr_sleep_cntrl(data, dxstate); - err = wait_event_timeout(data->gp0_wait_q, data->gp0_received, - msecs_to_jiffies(BTINTEL_DEFAULT_INTR_TIMEOUT_MS)); - if (err == 0) { - bt_dev_err(data->hdev, - "Timeout (%u ms) on alive interrupt for D3 entry", - BTINTEL_DEFAULT_INTR_TIMEOUT_MS); - return -EBUSY; - } + err = btintel_pcie_set_dxstate(data, dxstate); + + if (err) + return err; bt_dev_dbg(data->hdev, "device entered into d3 state from d0 in %lld us", ktime_to_us(ktime_get() - start)); - - return 0; + return err; } static int btintel_pcie_suspend(struct device *dev) @@ -2580,21 +2681,50 @@ static int btintel_pcie_resume(struct device *dev) start = ktime_get(); + /* When the system enters S4 (hibernate) mode, bluetooth device loses + * power, which results in the erasure of its loaded firmware. + * Consequently, function level reset (flr) is required on system + * resume to bring the controller back into an operational state by + * initiating a new firmware download. + */ + + if (data->pm_sx_event == PM_EVENT_FREEZE || + data->pm_sx_event == PM_EVENT_HIBERNATE) { + set_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags); + btintel_pcie_reset(data->hdev); + return 0; + } + /* Refer: 6.4.11.7 -> Platform power management */ - btintel_pcie_wr_sleep_cntrl(data, BTINTEL_PCIE_STATE_D0); - err = wait_event_timeout(data->gp0_wait_q, data->gp0_received, - msecs_to_jiffies(BTINTEL_DEFAULT_INTR_TIMEOUT_MS)); + err = btintel_pcie_set_dxstate(data, BTINTEL_PCIE_STATE_D0); + if (err == 0) { - bt_dev_err(data->hdev, - "Timeout (%u ms) on alive interrupt for D0 entry", - BTINTEL_DEFAULT_INTR_TIMEOUT_MS); - return -EBUSY; + bt_dev_dbg(data->hdev, + "device entered into d0 state from d3 in %lld us", + ktime_to_us(ktime_get() - start)); + return err; } - bt_dev_dbg(data->hdev, - "device entered into d0 state from d3 in %lld us", - ktime_to_us(ktime_get() - start)); - return 0; + /* Trigger function level reset if the controller is in error + * state during resume() to bring back the controller to + * operational mode + */ + + data->boot_stage_cache = btintel_pcie_rd_reg32(data, + BTINTEL_PCIE_CSR_BOOT_STAGE_REG); + if (btintel_pcie_in_error(data) || + btintel_pcie_in_device_halt(data)) { + bt_dev_err(data->hdev, "Controller in error state for D0 entry"); + if (!test_and_set_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, + &data->flags)) { + data->dmp_hdr.trigger_reason = + BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT; + queue_work(data->workqueue, &data->rx_work); + } + set_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags); + btintel_pcie_reset(data->hdev); + } + return err; } static const struct dev_pm_ops btintel_pcie_pm_ops = { diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h index 04b21f968ad3..e3d941ffef4a 100644 --- a/drivers/bluetooth/btintel_pcie.h +++ b/drivers/bluetooth/btintel_pcie.h @@ -158,6 +158,8 @@ enum msix_mbox_int_causes { /* Default interrupt timeout in msec */ #define BTINTEL_DEFAULT_INTR_TIMEOUT_MS 3000 +#define BTINTEL_PCIE_DX_TRANSITION_MAX_RETRIES 3 + /* The number of descriptors in TX queues */ #define BTINTEL_PCIE_TX_DESCS_COUNT 32 @@ -464,6 +466,7 @@ struct btintel_pcie_dump_header { * @txq: TX Queue struct * @rxq: RX Queue struct * @alive_intr_ctxt: Alive interrupt context + * @pm_sx_event: PM event on which system got suspended */ struct btintel_pcie_data { struct pci_dev *pdev; @@ -513,6 +516,7 @@ struct btintel_pcie_data { u32 alive_intr_ctxt; struct btintel_pcie_dbgc dbgc; struct btintel_pcie_dump_header dmp_hdr; + u8 pm_sx_event; }; static inline u32 btintel_pcie_rd_reg32(struct btintel_pcie_data *data, diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index 50abefba6d04..fba3ab6d30a5 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -615,7 +615,6 @@ static void btmtksdio_txrx_work(struct work_struct *work) sdio_release_host(bdev->func); - pm_runtime_mark_last_busy(bdev->dev); pm_runtime_put_autosuspend(bdev->dev); } @@ -1270,6 +1269,12 @@ static void btmtksdio_reset(struct hci_dev *hdev) sdio_claim_host(bdev->func); + /* set drv_pmctrl if BT is closed before doing reset */ + if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) { + sdio_enable_func(bdev->func); + btmtksdio_drv_pmctrl(bdev); + } + sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL); skb_queue_purge(&bdev->txq); cancel_work_sync(&bdev->txrx_work); @@ -1285,6 +1290,12 @@ static void btmtksdio_reset(struct hci_dev *hdev) goto err; } + /* set fw_pmctrl back if BT is closed after doing reset */ + if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) { + btmtksdio_fw_pmctrl(bdev); + sdio_disable_func(bdev->func); + } + clear_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state); err: sdio_release_host(bdev->func); diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c index d9b90ea2ad38..27aa48ff3ac2 100644 --- a/drivers/bluetooth/btmtkuart.c +++ b/drivers/bluetooth/btmtkuart.c @@ -79,6 +79,7 @@ struct btmtkuart_dev { u16 stp_dlen; const struct btmtkuart_data *data; + struct hci_uart hu; }; #define btmtkuart_is_standalone(bdev) \ @@ -368,7 +369,7 @@ static void btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) sz_left -= adv; p_left += adv; - bdev->rx_skb = h4_recv_buf(bdev->hdev, bdev->rx_skb, p_h4, + bdev->rx_skb = h4_recv_buf(&bdev->hu, bdev->rx_skb, p_h4, sz_h4, mtk_recv_pkts, ARRAY_SIZE(mtk_recv_pkts)); if (IS_ERR(bdev->rx_skb)) { @@ -858,6 +859,7 @@ static int btmtkuart_probe(struct serdev_device *serdev) } bdev->hdev = hdev; + bdev->hu.hdev = hdev; hdev->bus = HCI_UART; hci_set_drvdata(hdev, bdev); diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c index d5153fed0518..3b1e9224e965 100644 --- a/drivers/bluetooth/btnxpuart.c +++ b/drivers/bluetooth/btnxpuart.c @@ -212,6 +212,7 @@ struct btnxpuart_dev { struct ps_data psdata; struct btnxpuart_data *nxp_data; struct reset_control *pdn; + struct hci_uart hu; }; #define NXP_V1_FW_REQ_PKT 0xa5 @@ -1756,7 +1757,7 @@ static size_t btnxpuart_receive_buf(struct serdev_device *serdev, ps_start_timer(nxpdev); - nxpdev->rx_skb = h4_recv_buf(nxpdev->hdev, nxpdev->rx_skb, data, count, + nxpdev->rx_skb = h4_recv_buf(&nxpdev->hu, nxpdev->rx_skb, data, count, nxp_recv_pkts, ARRAY_SIZE(nxp_recv_pkts)); if (IS_ERR(nxpdev->rx_skb)) { int err = PTR_ERR(nxpdev->rx_skb); @@ -1875,6 +1876,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev) reset_control_deassert(nxpdev->pdn); nxpdev->hdev = hdev; + nxpdev->hu.hdev = hdev; hdev->bus = HCI_UART; hci_set_drvdata(hdev, nxpdev); diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index 6abd962502e3..5603b282f9bc 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -50,7 +50,7 @@ #define RTL_CHIP_SUBVER (&(struct rtl_vendor_cmd) {{0x10, 0x38, 0x04, 0x28, 0x80}}) #define RTL_CHIP_REV (&(struct rtl_vendor_cmd) {{0x10, 0x3A, 0x04, 0x28, 0x80}}) -#define RTL_SEC_PROJ (&(struct rtl_vendor_cmd) {{0x10, 0xA4, 0x0D, 0x00, 0xb0}}) +#define RTL_SEC_PROJ (&(struct rtl_vendor_cmd) {{0x10, 0xA4, 0xAD, 0x00, 0xb0}}) #define RTL_PATCH_SNIPPETS 0x01 #define RTL_PATCH_DUMMY_HEADER 0x02 @@ -72,6 +72,7 @@ enum btrtl_chip_id { CHIP_ID_8851B = 36, CHIP_ID_8922A = 44, CHIP_ID_8852BT = 47, + CHIP_ID_8761C = 51, }; struct id_table { @@ -230,6 +231,14 @@ static const struct id_table ic_id_table[] = { .cfg_name = "rtl_bt/rtl8761bu_config", .hw_info = "rtl8761bu" }, + /* 8761CU */ + { IC_INFO(RTL_ROM_LMP_8761A, 0x0e, 0, HCI_USB), + .config_needed = false, + .has_rom_version = true, + .fw_name = "rtl_bt/rtl8761cu_fw", + .cfg_name = "rtl_bt/rtl8761cu_config", + .hw_info = "rtl8761cu" }, + /* 8822C with UART interface */ { IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0x8, HCI_UART), .config_needed = true, @@ -344,7 +353,8 @@ static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev, (ic_id_table[i].hci_rev != hci_rev)) continue; if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIVER) && - (ic_id_table[i].hci_ver != hci_ver)) + (ic_id_table[i].hci_ver != hci_ver) && + (ic_id_table[i].hci_ver != 0)) continue; if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIBUS) && (ic_id_table[i].hci_bus != hci_bus)) @@ -534,7 +544,6 @@ static int rtlbt_parse_firmware_v2(struct hci_dev *hdev, { struct rtl_epatch_header_v2 *hdr; int rc; - u8 reg_val[2]; u8 key_id; u32 num_sections; struct rtl_section *section; @@ -549,14 +558,7 @@ static int rtlbt_parse_firmware_v2(struct hci_dev *hdev, .len = btrtl_dev->fw_len - 7, /* Cut the tail */ }; - rc = btrtl_vendor_read_reg16(hdev, RTL_SEC_PROJ, reg_val); - if (rc < 0) - return -EIO; - key_id = reg_val[0]; - - rtl_dev_dbg(hdev, "%s: key id %u", __func__, key_id); - - btrtl_dev->key_id = key_id; + key_id = btrtl_dev->key_id; hdr = rtl_iov_pull_data(&iov, sizeof(*hdr)); if (!hdr) @@ -625,8 +627,10 @@ static int rtlbt_parse_firmware_v2(struct hci_dev *hdev, len += entry->len; } - if (!len) + if (!len) { + kvfree(ptr); return -EPERM; + } *_buf = ptr; return len; @@ -668,6 +672,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, { RTL_ROM_LMP_8851B, 36 }, /* 8851B */ { RTL_ROM_LMP_8922A, 44 }, /* 8922A */ { RTL_ROM_LMP_8852A, 47 }, /* 8852BT */ + { RTL_ROM_LMP_8761A, 51 }, /* 8761C */ }; if (btrtl_dev->fw_len <= 8) @@ -1068,6 +1073,8 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, u16 hci_rev, lmp_subver; u8 hci_ver, lmp_ver, chip_type = 0; int ret; + int rc; + u8 key_id; u8 reg_val[2]; btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL); @@ -1178,6 +1185,14 @@ next: goto err_free; } + rc = btrtl_vendor_read_reg16(hdev, RTL_SEC_PROJ, reg_val); + if (rc < 0) + goto err_free; + + key_id = reg_val[0]; + btrtl_dev->key_id = key_id; + rtl_dev_info(hdev, "%s: key id %u", __func__, key_id); + btrtl_dev->fw_len = -EIO; if (lmp_subver == RTL_ROM_LMP_8852A && hci_rev == 0x000c) { snprintf(fw_name, sizeof(fw_name), "%s_v2.bin", @@ -1200,7 +1215,7 @@ next: goto err_free; } - if (btrtl_dev->ic_info->cfg_name) { + if (btrtl_dev->ic_info->cfg_name && !btrtl_dev->key_id) { if (postfix) { snprintf(cfg_name, sizeof(cfg_name), "%s-%s.bin", btrtl_dev->ic_info->cfg_name, postfix); @@ -1301,6 +1316,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev) case CHIP_ID_8851B: case CHIP_ID_8922A: case CHIP_ID_8852BT: + case CHIP_ID_8761C: hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED); /* RTL8852C needs to transmit mSBC data continuously without @@ -1520,6 +1536,8 @@ MODULE_FIRMWARE("rtl_bt/rtl8761b_fw.bin"); MODULE_FIRMWARE("rtl_bt/rtl8761b_config.bin"); MODULE_FIRMWARE("rtl_bt/rtl8761bu_fw.bin"); MODULE_FIRMWARE("rtl_bt/rtl8761bu_config.bin"); +MODULE_FIRMWARE("rtl_bt/rtl8761cu_fw.bin"); +MODULE_FIRMWARE("rtl_bt/rtl8761cu_config.bin"); MODULE_FIRMWARE("rtl_bt/rtl8821a_fw.bin"); MODULE_FIRMWARE("rtl_bt/rtl8821a_config.bin"); MODULE_FIRMWARE("rtl_bt/rtl8821c_fw.bin"); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 5e9ebf0c5312..8ed3883ab8ee 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -504,6 +504,8 @@ static const struct usb_device_id quirks_table[] = { /* Realtek 8821CE Bluetooth devices */ { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3533), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Realtek 8822CE Bluetooth devices */ { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | @@ -585,6 +587,12 @@ static const struct usb_device_id quirks_table[] = { /* Realtek 8852BT/8852BE-VT Bluetooth devices */ { USB_DEVICE(0x0bda, 0x8520), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe12f), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3618), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3619), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Realtek 8922AE Bluetooth devices */ { USB_DEVICE(0x0bda, 0x8922), .driver_info = BTUSB_REALTEK | @@ -621,6 +629,8 @@ static const struct usb_device_id quirks_table[] = { /* Additional MediaTek MT7920 Bluetooth devices */ { USB_DEVICE(0x0489, 0xe134), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe135), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3620), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3621), .driver_info = BTUSB_MEDIATEK | @@ -685,6 +695,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0489, 0xe153), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe170), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x04ca, 0x38e4), .driver_info = BTUSB_MEDIATEK | @@ -781,6 +793,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x2b89, 0x6275), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Additional Realtek 8821AE Bluetooth devices */ { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, @@ -1131,6 +1145,24 @@ static void btusb_qca_reset(struct hci_dev *hdev) btusb_reset(hdev); } +static u8 btusb_classify_qca_pkt_type(struct hci_dev *hdev, struct sk_buff *skb) +{ + /* Some Qualcomm controllers, e.g., QCNFA765 with WCN6855 chip, send debug + * packets as ACL frames with connection handle 0x2EDC. These are not real + * ACL packets and should be reclassified as HCI_DIAG_PKT to prevent + * "ACL packet for unknown connection handle 3804" errors. + */ + if (skb->len >= 2) { + u16 handle = get_unaligned_le16(skb->data); + + if (handle == 0x2EDC) + return HCI_DIAG_PKT; + } + + /* Use default packet type for other packets */ + return hci_skb_pkt_type(skb); +} + static inline void btusb_free_frags(struct btusb_data *data) { unsigned long flags; @@ -2711,9 +2743,21 @@ static int btusb_recv_event_realtek(struct hci_dev *hdev, struct sk_buff *skb) static void btusb_mtk_claim_iso_intf(struct btusb_data *data) { - struct btmtk_data *btmtk_data = hci_get_priv(data->hdev); + struct btmtk_data *btmtk_data; int err; + if (!data->hdev) + return; + + btmtk_data = hci_get_priv(data->hdev); + if (!btmtk_data) + return; + + if (!btmtk_data->isopkt_intf) { + bt_dev_err(data->hdev, "Can't claim NULL iso interface"); + return; + } + /* * The function usb_driver_claim_interface() is documented to need * locks held if it's not called from a probe routine. The code here @@ -2735,17 +2779,30 @@ static void btusb_mtk_claim_iso_intf(struct btusb_data *data) static void btusb_mtk_release_iso_intf(struct hci_dev *hdev) { - struct btmtk_data *btmtk_data = hci_get_priv(hdev); + struct btmtk_data *btmtk_data; + + if (!hdev) + return; + + btmtk_data = hci_get_priv(hdev); + if (!btmtk_data) + return; if (test_bit(BTMTK_ISOPKT_OVER_INTR, &btmtk_data->flags)) { usb_kill_anchored_urbs(&btmtk_data->isopkt_anchor); clear_bit(BTMTK_ISOPKT_RUNNING, &btmtk_data->flags); - dev_kfree_skb_irq(btmtk_data->isopkt_skb); - btmtk_data->isopkt_skb = NULL; - usb_set_intfdata(btmtk_data->isopkt_intf, NULL); - usb_driver_release_interface(&btusb_driver, - btmtk_data->isopkt_intf); + if (btmtk_data->isopkt_skb) { + dev_kfree_skb_irq(btmtk_data->isopkt_skb); + btmtk_data->isopkt_skb = NULL; + } + + if (btmtk_data->isopkt_intf) { + usb_set_intfdata(btmtk_data->isopkt_intf, NULL); + usb_driver_release_interface(&btusb_driver, + btmtk_data->isopkt_intf); + btmtk_data->isopkt_intf = NULL; + } } clear_bit(BTMTK_ISOPKT_OVER_INTR, &btmtk_data->flags); @@ -2783,6 +2840,19 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data) btusb_stop_traffic(data); usb_kill_anchored_urbs(&data->tx_anchor); + /* Toggle the hard reset line. The MediaTek device is going to + * yank itself off the USB and then replug. The cleanup is handled + * correctly on the way out (standard USB disconnect), and the new + * device is detected cleanly and bound to the driver again like + * it should be. + */ + if (data->reset_gpio) { + gpiod_set_value_cansleep(data->reset_gpio, 1); + msleep(200); + gpiod_set_value_cansleep(data->reset_gpio, 0); + return 0; + } + err = btmtk_usb_subsys_reset(hdev, btmtk_data->dev_id); usb_queue_reset_device(data->intf); @@ -3236,6 +3306,7 @@ static const struct qca_device_info qca_devices_table[] = { static const struct qca_custom_firmware qca_custom_btfws[] = { { 0x00130201, 0x030A, "QCA2066" }, + { 0x00130201, 0x030B, "QCA2066" }, { }, }; @@ -4201,6 +4272,7 @@ static int btusb_probe(struct usb_interface *intf, data->recv_acl = btusb_recv_acl_qca; hci_devcd_register(hdev, btusb_coredump_qca, btusb_dump_hdr_qca, NULL); data->setup_on_usb = btusb_setup_qca; + hdev->classify_pkt_type = btusb_classify_qca_pkt_type; hdev->shutdown = btusb_shutdown_qca; hdev->set_bdaddr = btusb_set_bdaddr_wcn6855; hdev->reset = btusb_qca_reset; @@ -4361,6 +4433,11 @@ static void btusb_disconnect(struct usb_interface *intf) hci_unregister_dev(hdev); + if (data->oob_wake_irq) + device_init_wakeup(&data->udev->dev, false); + if (data->reset_gpio) + gpiod_put(data->reset_gpio); + if (intf == data->intf) { if (data->isoc) usb_driver_release_interface(&btusb_driver, data->isoc); @@ -4371,17 +4448,11 @@ static void btusb_disconnect(struct usb_interface *intf) usb_driver_release_interface(&btusb_driver, data->diag); usb_driver_release_interface(&btusb_driver, data->intf); } else if (intf == data->diag) { - usb_driver_release_interface(&btusb_driver, data->intf); if (data->isoc) usb_driver_release_interface(&btusb_driver, data->isoc); + usb_driver_release_interface(&btusb_driver, data->intf); } - if (data->oob_wake_irq) - device_init_wakeup(&data->udev->dev, false); - - if (data->reset_gpio) - gpiod_put(data->reset_gpio); - hci_free_dev(hdev); } diff --git a/drivers/bluetooth/hci_ag6xx.c b/drivers/bluetooth/hci_ag6xx.c index 2d40302409ff..94588676510f 100644 --- a/drivers/bluetooth/hci_ag6xx.c +++ b/drivers/bluetooth/hci_ag6xx.c @@ -105,7 +105,7 @@ static int ag6xx_recv(struct hci_uart *hu, const void *data, int count) if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) return -EUNATCH; - ag6xx->rx_skb = h4_recv_buf(hu->hdev, ag6xx->rx_skb, data, count, + ag6xx->rx_skb = h4_recv_buf(hu, ag6xx->rx_skb, data, count, ag6xx_recv_pkts, ARRAY_SIZE(ag6xx_recv_pkts)); if (IS_ERR(ag6xx->rx_skb)) { diff --git a/drivers/bluetooth/hci_aml.c b/drivers/bluetooth/hci_aml.c index 707e90f80130..b1f32c5a8a3f 100644 --- a/drivers/bluetooth/hci_aml.c +++ b/drivers/bluetooth/hci_aml.c @@ -650,7 +650,7 @@ static int aml_recv(struct hci_uart *hu, const void *data, int count) struct aml_data *aml_data = hu->priv; int err; - aml_data->rx_skb = h4_recv_buf(hu->hdev, aml_data->rx_skb, data, count, + aml_data->rx_skb = h4_recv_buf(hu, aml_data->rx_skb, data, count, aml_recv_pkts, ARRAY_SIZE(aml_recv_pkts)); if (IS_ERR(aml_data->rx_skb)) { diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index dbfe34664633..8d2b5e7f0d6a 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -191,7 +191,7 @@ static int ath_recv(struct hci_uart *hu, const void *data, int count) { struct ath_struct *ath = hu->priv; - ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count, + ath->rx_skb = h4_recv_buf(hu, ath->rx_skb, data, count, ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts)); if (IS_ERR(ath->rx_skb)) { int err = PTR_ERR(ath->rx_skb); diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index f96617b85d87..9286a5f40f55 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -326,7 +326,6 @@ static irqreturn_t bcm_host_wake(int irq, void *data) bt_dev_dbg(bdev, "Host wake IRQ"); pm_runtime_get(bdev->dev); - pm_runtime_mark_last_busy(bdev->dev); pm_runtime_put_autosuspend(bdev->dev); return IRQ_HANDLED; @@ -698,7 +697,7 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count) if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) return -EUNATCH; - bcm->rx_skb = h4_recv_buf(hu->hdev, bcm->rx_skb, data, count, + bcm->rx_skb = h4_recv_buf(hu, bcm->rx_skb, data, count, bcm_recv_pkts, ARRAY_SIZE(bcm_recv_pkts)); if (IS_ERR(bcm->rx_skb)) { int err = PTR_ERR(bcm->rx_skb); @@ -710,7 +709,6 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count) mutex_lock(&bcm_device_lock); if (bcm->dev && bcm_device_exists(bcm->dev)) { pm_runtime_get(bcm->dev->dev); - pm_runtime_mark_last_busy(bcm->dev->dev); pm_runtime_put_autosuspend(bcm->dev->dev); } mutex_unlock(&bcm_device_lock); @@ -748,10 +746,8 @@ static struct sk_buff *bcm_dequeue(struct hci_uart *hu) skb = skb_dequeue(&bcm->txq); - if (bdev) { - pm_runtime_mark_last_busy(bdev->dev); + if (bdev) pm_runtime_put_autosuspend(bdev->dev); - } mutex_unlock(&bcm_device_lock); diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 9070e31a68bf..ec017df8572c 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -112,7 +112,7 @@ static int h4_recv(struct hci_uart *hu, const void *data, int count) if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) return -EUNATCH; - h4->rx_skb = h4_recv_buf(hu->hdev, h4->rx_skb, data, count, + h4->rx_skb = h4_recv_buf(hu, h4->rx_skb, data, count, h4_recv_pkts, ARRAY_SIZE(h4_recv_pkts)); if (IS_ERR(h4->rx_skb)) { int err = PTR_ERR(h4->rx_skb); @@ -151,12 +151,12 @@ int __exit h4_deinit(void) return hci_uart_unregister_proto(&h4p); } -struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb, +struct sk_buff *h4_recv_buf(struct hci_uart *hu, struct sk_buff *skb, const unsigned char *buffer, int count, const struct h4_recv_pkt *pkts, int pkts_count) { - struct hci_uart *hu = hci_get_drvdata(hdev); u8 alignment = hu->alignment ? hu->alignment : 1; + struct hci_dev *hdev = hu->hdev; /* Check for error from previous call */ if (IS_ERR(skb)) diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index d0d4420c1a0f..96e20a66ecd1 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -7,6 +7,8 @@ */ #include <linux/acpi.h> +#include <linux/bitrev.h> +#include <linux/crc-ccitt.h> #include <linux/errno.h> #include <linux/gpio/consumer.h> #include <linux/kernel.h> @@ -58,6 +60,7 @@ enum { H5_TX_ACK_REQ, /* Pending ack to send */ H5_WAKEUP_DISABLE, /* Device cannot wake host */ H5_HW_FLOW_CONTROL, /* Use HW flow control */ + H5_CRC, /* Use CRC */ }; struct h5 { @@ -141,8 +144,8 @@ static void h5_link_control(struct hci_uart *hu, const void *data, size_t len) static u8 h5_cfg_field(struct h5 *h5) { - /* Sliding window size (first 3 bits) */ - return h5->tx_win & 0x07; + /* Sliding window size (first 3 bits) and CRC request (fifth bit). */ + return (h5->tx_win & 0x07) | 0x10; } static void h5_timed_event(struct timer_list *t) @@ -213,7 +216,6 @@ static void h5_peer_reset(struct hci_uart *hu) static int h5_open(struct hci_uart *hu) { struct h5 *h5; - const unsigned char sync[] = { 0x01, 0x7e }; BT_DBG("hu %p", hu); @@ -243,9 +245,11 @@ static int h5_open(struct hci_uart *hu) set_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags); - /* Send initial sync request */ - h5_link_control(hu, sync, sizeof(sync)); - mod_timer(&h5->timer, jiffies + H5_SYNC_TIMEOUT); + /* + * Wait one jiffy because the UART layer won't set HCI_UART_PROTO_READY, + * which allows us to send link packets, until this function returns. + */ + mod_timer(&h5->timer, jiffies + 1); return 0; } @@ -360,8 +364,10 @@ static void h5_handle_internal_rx(struct hci_uart *hu) h5_link_control(hu, conf_rsp, 2); h5_link_control(hu, conf_req, 3); } else if (memcmp(data, conf_rsp, 2) == 0) { - if (H5_HDR_LEN(hdr) > 2) + if (H5_HDR_LEN(hdr) > 2) { h5->tx_win = (data[2] & 0x07); + assign_bit(H5_CRC, &h5->flags, data[2] & 0x10); + } BT_DBG("Three-wire init complete. tx_win %u", h5->tx_win); h5->state = H5_ACTIVE; hci_uart_init_ready(hu); @@ -425,7 +431,24 @@ static void h5_complete_rx_pkt(struct hci_uart *hu) static int h5_rx_crc(struct hci_uart *hu, unsigned char c) { - h5_complete_rx_pkt(hu); + struct h5 *h5 = hu->priv; + const unsigned char *hdr = h5->rx_skb->data; + u16 crc; + __be16 crc_be; + + crc = crc_ccitt(0xffff, hdr, 4 + H5_HDR_LEN(hdr)); + crc = bitrev16(crc); + + crc_be = cpu_to_be16(crc); + + if (memcmp(&crc_be, hdr + 4 + H5_HDR_LEN(hdr), 2) != 0) { + bt_dev_err(hu->hdev, "Received packet with invalid CRC"); + h5_reset_rx(h5); + } else { + /* Remove CRC bytes */ + skb_trim(h5->rx_skb, 4 + H5_HDR_LEN(hdr)); + h5_complete_rx_pkt(hu); + } return 0; } @@ -556,6 +579,7 @@ static void h5_reset_rx(struct h5 *h5) h5->rx_func = h5_rx_delimiter; h5->rx_pending = 0; clear_bit(H5_RX_ESC, &h5->flags); + clear_bit(H5_CRC, &h5->flags); } static int h5_recv(struct hci_uart *hu, const void *data, int count) @@ -592,7 +616,6 @@ static int h5_recv(struct hci_uart *hu, const void *data, int count) if (hu->serdev) { pm_runtime_get(&hu->serdev->dev); - pm_runtime_mark_last_busy(&hu->serdev->dev); pm_runtime_put_autosuspend(&hu->serdev->dev); } @@ -634,7 +657,6 @@ static int h5_enqueue(struct hci_uart *hu, struct sk_buff *skb) if (hu->serdev) { pm_runtime_get_sync(&hu->serdev->dev); - pm_runtime_mark_last_busy(&hu->serdev->dev); pm_runtime_put_autosuspend(&hu->serdev->dev); } @@ -686,6 +708,7 @@ static struct sk_buff *h5_prepare_pkt(struct hci_uart *hu, u8 pkt_type, struct h5 *h5 = hu->priv; struct sk_buff *nskb; u8 hdr[4]; + u16 crc; int i; if (!valid_packet_type(pkt_type)) { @@ -713,6 +736,7 @@ static struct sk_buff *h5_prepare_pkt(struct hci_uart *hu, u8 pkt_type, /* Reliable packet? */ if (pkt_type == HCI_ACLDATA_PKT || pkt_type == HCI_COMMAND_PKT) { hdr[0] |= 1 << 7; + hdr[0] |= (test_bit(H5_CRC, &h5->flags) && 1) << 6; hdr[0] |= h5->tx_seq; h5->tx_seq = (h5->tx_seq + 1) % 8; } @@ -732,6 +756,15 @@ static struct sk_buff *h5_prepare_pkt(struct hci_uart *hu, u8 pkt_type, for (i = 0; i < len; i++) h5_slip_one_byte(nskb, data[i]); + if (H5_HDR_CRC(hdr)) { + crc = crc_ccitt(0xffff, hdr, 4); + crc = crc_ccitt(crc, data, len); + crc = bitrev16(crc); + + h5_slip_one_byte(nskb, (crc >> 8) & 0xff); + h5_slip_one_byte(nskb, crc & 0xff); + } + h5_slip_delim(nskb); return nskb; diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index 9b353c3d6442..20baf2895dec 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -280,7 +280,6 @@ static irqreturn_t intel_irq(int irq, void *dev_id) /* Host/Controller are now LPM resumed, trigger a new delayed suspend */ pm_runtime_get(&idev->pdev->dev); - pm_runtime_mark_last_busy(&idev->pdev->dev); pm_runtime_put_autosuspend(&idev->pdev->dev); return IRQ_HANDLED; @@ -371,7 +370,6 @@ static void intel_busy_work(struct work_struct *work) list_for_each_entry(idev, &intel_device_list, list) { if (intel->hu->tty->dev->parent == idev->pdev->dev.parent) { pm_runtime_get(&idev->pdev->dev); - pm_runtime_mark_last_busy(&idev->pdev->dev); pm_runtime_put_autosuspend(&idev->pdev->dev); break; } @@ -972,7 +970,7 @@ static int intel_recv(struct hci_uart *hu, const void *data, int count) if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) return -EUNATCH; - intel->rx_skb = h4_recv_buf(hu->hdev, intel->rx_skb, data, count, + intel->rx_skb = h4_recv_buf(hu, intel->rx_skb, data, count, intel_recv_pkts, ARRAY_SIZE(intel_recv_pkts)); if (IS_ERR(intel->rx_skb)) { @@ -1003,7 +1001,6 @@ static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb) list_for_each_entry(idev, &intel_device_list, list) { if (hu->tty->dev->parent == idev->pdev->dev.parent) { pm_runtime_get_sync(&idev->pdev->dev); - pm_runtime_mark_last_busy(&idev->pdev->dev); pm_runtime_put_autosuspend(&idev->pdev->dev); break; } diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index 7044c86325ce..6f4e25917b86 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -429,7 +429,7 @@ static int ll_recv(struct hci_uart *hu, const void *data, int count) if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) return -EUNATCH; - ll->rx_skb = h4_recv_buf(hu->hdev, ll->rx_skb, data, count, + ll->rx_skb = h4_recv_buf(hu, ll->rx_skb, data, count, ll_recv_pkts, ARRAY_SIZE(ll_recv_pkts)); if (IS_ERR(ll->rx_skb)) { int err = PTR_ERR(ll->rx_skb); diff --git a/drivers/bluetooth/hci_mrvl.c b/drivers/bluetooth/hci_mrvl.c index e08222395772..8767522ec4c6 100644 --- a/drivers/bluetooth/hci_mrvl.c +++ b/drivers/bluetooth/hci_mrvl.c @@ -264,9 +264,9 @@ static int mrvl_recv(struct hci_uart *hu, const void *data, int count) !test_bit(STATE_FW_LOADED, &mrvl->flags)) return count; - mrvl->rx_skb = h4_recv_buf(hu->hdev, mrvl->rx_skb, data, count, - mrvl_recv_pkts, - ARRAY_SIZE(mrvl_recv_pkts)); + mrvl->rx_skb = h4_recv_buf(hu, mrvl->rx_skb, data, count, + mrvl_recv_pkts, + ARRAY_SIZE(mrvl_recv_pkts)); if (IS_ERR(mrvl->rx_skb)) { int err = PTR_ERR(mrvl->rx_skb); bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err); diff --git a/drivers/bluetooth/hci_nokia.c b/drivers/bluetooth/hci_nokia.c index cd7575c20f65..1e65b541f8ad 100644 --- a/drivers/bluetooth/hci_nokia.c +++ b/drivers/bluetooth/hci_nokia.c @@ -624,8 +624,8 @@ static int nokia_recv(struct hci_uart *hu, const void *data, int count) if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) return -EUNATCH; - btdev->rx_skb = h4_recv_buf(hu->hdev, btdev->rx_skb, data, count, - nokia_recv_pkts, ARRAY_SIZE(nokia_recv_pkts)); + btdev->rx_skb = h4_recv_buf(hu, btdev->rx_skb, data, count, + nokia_recv_pkts, ARRAY_SIZE(nokia_recv_pkts)); if (IS_ERR(btdev->rx_skb)) { err = PTR_ERR(btdev->rx_skb); dev_err(dev, "Frame reassembly failed (%d)", err); diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 4cff4d9be313..888176b0faa9 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1277,7 +1277,7 @@ static int qca_recv(struct hci_uart *hu, const void *data, int count) if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) return -EUNATCH; - qca->rx_skb = h4_recv_buf(hu->hdev, qca->rx_skb, data, count, + qca->rx_skb = h4_recv_buf(hu, qca->rx_skb, data, count, qca_recv_pkts, ARRAY_SIZE(qca_recv_pkts)); if (IS_ERR(qca->rx_skb)) { int err = PTR_ERR(qca->rx_skb); diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index cbbe79b241ce..48ac7ca9334e 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -162,7 +162,7 @@ struct h4_recv_pkt { int h4_init(void); int h4_deinit(void); -struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb, +struct sk_buff *h4_recv_buf(struct hci_uart *hu, struct sk_buff *skb, const unsigned char *buffer, int count, const struct h4_recv_pkt *pkts, int pkts_count); #endif |
