You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says: ==================== pull request: bluetooth-next 2020-07-31 Here's the main bluetooth-next pull request for 5.9: - Fix firmware filenames for Marvell chipsets - Several suspend-related fixes - Addedd mgmt commands for runtime configuration - Multiple fixes for Qualcomm-based controllers - Add new monitoring feature for mgmt - Fix handling of legacy cipher (E4) together with security level 4 - Add support for Realtek 8822CE controller - Fix issues with Chinese controllers using fake VID/PID values - Multiple other smaller fixes & improvements ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -44,7 +44,7 @@ examples:
|
||||
uart1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
|
||||
uart-has-rtscts = <1>;
|
||||
uart-has-rtscts;
|
||||
|
||||
bluetooth {
|
||||
compatible = "realtek,rtl8723bs-bt";
|
||||
|
||||
@@ -106,7 +106,7 @@ static void bcm203x_complete(struct urb *urb)
|
||||
}
|
||||
|
||||
data->state = BCM203X_LOAD_FIRMWARE;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case BCM203X_LOAD_FIRMWARE:
|
||||
if (data->fw_sent == data->fw_size) {
|
||||
usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP),
|
||||
|
||||
@@ -295,7 +295,6 @@ static void bluecard_write_wakeup(struct bluecard_info *info)
|
||||
baud_reg = REG_CONTROL_BAUD_RATE_115200;
|
||||
break;
|
||||
case PKT_BAUD_RATE_57600:
|
||||
/* Fall through... */
|
||||
default:
|
||||
baud_reg = REG_CONTROL_BAUD_RATE_57600;
|
||||
break;
|
||||
@@ -585,7 +584,6 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
|
||||
hci_skb_pkt_type(skb) = PKT_BAUD_RATE_115200;
|
||||
break;
|
||||
case 57600:
|
||||
/* Fall through... */
|
||||
default:
|
||||
cmd[4] = 0x03;
|
||||
hci_skb_pkt_type(skb) = PKT_BAUD_RATE_57600;
|
||||
|
||||
@@ -754,6 +754,65 @@ void btintel_reset_to_bootloader(struct hci_dev *hdev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btintel_reset_to_bootloader);
|
||||
|
||||
int btintel_read_debug_features(struct hci_dev *hdev,
|
||||
struct intel_debug_features *features)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u8 page_no = 1;
|
||||
|
||||
/* Intel controller supports two pages, each page is of 128-bit
|
||||
* feature bit mask. And each bit defines specific feature support
|
||||
*/
|
||||
skb = __hci_cmd_sync(hdev, 0xfca6, sizeof(page_no), &page_no,
|
||||
HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Reading supported features failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
if (skb->len != (sizeof(features->page1) + 3)) {
|
||||
bt_dev_err(hdev, "Supported features event size mismatch");
|
||||
kfree_skb(skb);
|
||||
return -EILSEQ;
|
||||
}
|
||||
|
||||
memcpy(features->page1, skb->data + 3, sizeof(features->page1));
|
||||
|
||||
/* Read the supported features page2 if required in future.
|
||||
*/
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btintel_read_debug_features);
|
||||
|
||||
int btintel_set_debug_features(struct hci_dev *hdev,
|
||||
const struct intel_debug_features *features)
|
||||
{
|
||||
u8 mask[11] = { 0x0a, 0x92, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00 };
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!features)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(features->page1[0] & 0x3f)) {
|
||||
bt_dev_info(hdev, "Telemetry exception format not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc8b, 11, mask, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Setting Intel telemetry ddc write event mask failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btintel_set_debug_features);
|
||||
|
||||
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
|
||||
MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION);
|
||||
MODULE_VERSION(VERSION);
|
||||
|
||||
@@ -62,6 +62,10 @@ struct intel_reset {
|
||||
__le32 boot_param;
|
||||
} __packed;
|
||||
|
||||
struct intel_debug_features {
|
||||
__u8 page1[16];
|
||||
} __packed;
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_INTEL)
|
||||
|
||||
int btintel_check_bdaddr(struct hci_dev *hdev);
|
||||
@@ -88,6 +92,10 @@ int btintel_read_boot_params(struct hci_dev *hdev,
|
||||
int btintel_download_firmware(struct hci_dev *dev, const struct firmware *fw,
|
||||
u32 *boot_param);
|
||||
void btintel_reset_to_bootloader(struct hci_dev *hdev);
|
||||
int btintel_read_debug_features(struct hci_dev *hdev,
|
||||
struct intel_debug_features *features);
|
||||
int btintel_set_debug_features(struct hci_dev *hdev,
|
||||
const struct intel_debug_features *features);
|
||||
#else
|
||||
|
||||
static inline int btintel_check_bdaddr(struct hci_dev *hdev)
|
||||
@@ -186,4 +194,17 @@ static inline int btintel_download_firmware(struct hci_dev *dev,
|
||||
static inline void btintel_reset_to_bootloader(struct hci_dev *hdev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int btintel_read_debug_features(struct hci_dev *hdev,
|
||||
struct intel_debug_features *features)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int btintel_set_debug_features(struct hci_dev *hdev,
|
||||
const struct intel_debug_features *features)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -587,6 +587,14 @@ static int btmrvl_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool btmrvl_prevent_wake(struct hci_dev *hdev)
|
||||
{
|
||||
struct btmrvl_private *priv = hci_get_drvdata(hdev);
|
||||
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
|
||||
|
||||
return !device_may_wakeup(&card->func->dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the event generated by firmware, rx data
|
||||
* received from firmware, and tx data sent from kernel.
|
||||
@@ -669,6 +677,7 @@ static int btmrvl_service_main_thread(void *data)
|
||||
int btmrvl_register_hdev(struct btmrvl_private *priv)
|
||||
{
|
||||
struct hci_dev *hdev = NULL;
|
||||
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
|
||||
int ret;
|
||||
|
||||
hdev = hci_alloc_dev();
|
||||
@@ -687,6 +696,8 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
|
||||
hdev->send = btmrvl_send_frame;
|
||||
hdev->setup = btmrvl_setup;
|
||||
hdev->set_bdaddr = btmrvl_set_bdaddr;
|
||||
hdev->prevent_wake = btmrvl_prevent_wake;
|
||||
SET_HCIDEV_DEV(hdev, &card->func->dev);
|
||||
|
||||
hdev->dev_type = priv->btmrvl_dev.dev_type;
|
||||
|
||||
|
||||
@@ -111,6 +111,9 @@ static int btmrvl_sdio_probe_of(struct device *dev,
|
||||
"Failed to request irq_bt %d (%d)\n",
|
||||
cfg->irq_bt, ret);
|
||||
}
|
||||
|
||||
/* Configure wakeup (enabled by default) */
|
||||
device_init_wakeup(dev, true);
|
||||
disable_irq(cfg->irq_bt);
|
||||
}
|
||||
}
|
||||
@@ -328,7 +331,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
|
||||
|
||||
static const struct btmrvl_sdio_device btmrvl_sdio_sd8977 = {
|
||||
.helper = NULL,
|
||||
.firmware = "mrvl/sd8977_uapsta.bin",
|
||||
.firmware = "mrvl/sdsd8977_combo_v2.bin",
|
||||
.reg = &btmrvl_reg_8977,
|
||||
.support_pscan_win_report = true,
|
||||
.sd_blksz_fw_dl = 256,
|
||||
@@ -346,7 +349,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8987 = {
|
||||
|
||||
static const struct btmrvl_sdio_device btmrvl_sdio_sd8997 = {
|
||||
.helper = NULL,
|
||||
.firmware = "mrvl/sd8997_uapsta.bin",
|
||||
.firmware = "mrvl/sdsd8997_combo_v4.bin",
|
||||
.reg = &btmrvl_reg_8997,
|
||||
.support_pscan_win_report = true,
|
||||
.sd_blksz_fw_dl = 256,
|
||||
@@ -1654,6 +1657,7 @@ static void btmrvl_sdio_remove(struct sdio_func *func)
|
||||
MODULE_SHUTDOWN_REQ);
|
||||
btmrvl_sdio_disable_host_int(card);
|
||||
}
|
||||
|
||||
BT_DBG("unregister dev");
|
||||
card->priv->surprise_removed = true;
|
||||
btmrvl_sdio_unregister_dev(card);
|
||||
@@ -1690,7 +1694,8 @@ static int btmrvl_sdio_suspend(struct device *dev)
|
||||
}
|
||||
|
||||
/* Enable platform specific wakeup interrupt */
|
||||
if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) {
|
||||
if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 &&
|
||||
device_may_wakeup(dev)) {
|
||||
card->plt_wake_cfg->wake_by_bt = false;
|
||||
enable_irq(card->plt_wake_cfg->irq_bt);
|
||||
enable_irq_wake(card->plt_wake_cfg->irq_bt);
|
||||
@@ -1707,7 +1712,8 @@ static int btmrvl_sdio_suspend(struct device *dev)
|
||||
BT_ERR("HS not activated, suspend failed!");
|
||||
/* Disable platform specific wakeup interrupt */
|
||||
if (card->plt_wake_cfg &&
|
||||
card->plt_wake_cfg->irq_bt >= 0) {
|
||||
card->plt_wake_cfg->irq_bt >= 0 &&
|
||||
device_may_wakeup(dev)) {
|
||||
disable_irq_wake(card->plt_wake_cfg->irq_bt);
|
||||
disable_irq(card->plt_wake_cfg->irq_bt);
|
||||
}
|
||||
@@ -1767,7 +1773,8 @@ static int btmrvl_sdio_resume(struct device *dev)
|
||||
hci_resume_dev(hcidev);
|
||||
|
||||
/* Disable platform specific wakeup interrupt */
|
||||
if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) {
|
||||
if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 &&
|
||||
device_may_wakeup(dev)) {
|
||||
disable_irq_wake(card->plt_wake_cfg->irq_bt);
|
||||
disable_irq(card->plt_wake_cfg->irq_bt);
|
||||
if (card->plt_wake_cfg->wake_by_bt)
|
||||
@@ -1831,6 +1838,6 @@ MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
|
||||
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
|
||||
MODULE_FIRMWARE("mrvl/sd8887_uapsta.bin");
|
||||
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
|
||||
MODULE_FIRMWARE("mrvl/sd8977_uapsta.bin");
|
||||
MODULE_FIRMWARE("mrvl/sdsd8977_combo_v2.bin");
|
||||
MODULE_FIRMWARE("mrvl/sd8987_uapsta.bin");
|
||||
MODULE_FIRMWARE("mrvl/sd8997_uapsta.bin");
|
||||
MODULE_FIRMWARE("mrvl/sdsd8997_combo_v4.bin");
|
||||
|
||||
@@ -685,7 +685,7 @@ static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
|
||||
const u8 *fw_ptr;
|
||||
size_t fw_size;
|
||||
int err, dlen;
|
||||
u8 flag;
|
||||
u8 flag, param;
|
||||
|
||||
err = request_firmware(&fw, fwname, &hdev->dev);
|
||||
if (err < 0) {
|
||||
@@ -693,6 +693,20 @@ static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Power on data RAM the firmware relies on. */
|
||||
param = 1;
|
||||
wmt_params.op = MTK_WMT_FUNC_CTRL;
|
||||
wmt_params.flag = 3;
|
||||
wmt_params.dlen = sizeof(param);
|
||||
wmt_params.data = ¶m;
|
||||
wmt_params.status = NULL;
|
||||
|
||||
err = mtk_hci_wmt_sync(hdev, &wmt_params);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
fw_ptr = fw->data;
|
||||
fw_size = fw->size;
|
||||
|
||||
|
||||
@@ -400,6 +400,27 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qca_disable_soc_logging(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u8 cmd[2];
|
||||
int err;
|
||||
|
||||
cmd[0] = QCA_DISABLE_LOGGING_SUB_OP;
|
||||
cmd[1] = 0x00;
|
||||
skb = __hci_cmd_sync_ev(hdev, QCA_DISABLE_LOGGING, sizeof(cmd), cmd,
|
||||
HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "QCA Failed to disable soc logging(%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@@ -486,6 +507,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
return err;
|
||||
}
|
||||
|
||||
if (soc_type >= QCA_WCN3991) {
|
||||
err = qca_disable_soc_logging(hdev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Perform HCI reset */
|
||||
err = qca_send_reset(hdev);
|
||||
if (err < 0) {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define EDL_NVM_ACCESS_SET_REQ_CMD (0x01)
|
||||
#define MAX_SIZE_PER_TLV_SEGMENT (243)
|
||||
#define QCA_PRE_SHUTDOWN_CMD (0xFC08)
|
||||
#define QCA_DISABLE_LOGGING (0xFC17)
|
||||
|
||||
#define EDL_CMD_REQ_RES_EVT (0x00)
|
||||
#define EDL_PATCH_VER_RES_EVT (0x19)
|
||||
@@ -22,6 +23,7 @@
|
||||
#define EDL_CMD_EXE_STATUS_EVT (0x00)
|
||||
#define EDL_SET_BAUDRATE_RSP_EVT (0x92)
|
||||
#define EDL_NVM_ACCESS_CODE_EVT (0x0B)
|
||||
#define QCA_DISABLE_LOGGING_SUB_OP (0x14)
|
||||
|
||||
#define EDL_TAG_ID_HCI (17)
|
||||
#define EDL_TAG_ID_DEEP_SLEEP (27)
|
||||
|
||||
@@ -359,6 +359,10 @@ static const struct usb_device_id blacklist_table[] = {
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01),
|
||||
.driver_info = BTUSB_IGNORE },
|
||||
|
||||
/* Realtek 8822CE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek Bluetooth devices */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
|
||||
.driver_info = BTUSB_REALTEK },
|
||||
@@ -453,6 +457,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
|
||||
#define BTUSB_HW_RESET_ACTIVE 12
|
||||
#define BTUSB_TX_WAIT_VND_EVT 13
|
||||
#define BTUSB_WAKEUP_DISABLE 14
|
||||
#define BTUSB_USE_ALT1_FOR_WBS 15
|
||||
|
||||
struct btusb_data {
|
||||
struct hci_dev *hdev;
|
||||
@@ -511,7 +516,6 @@ struct btusb_data {
|
||||
unsigned cmd_timeout_cnt;
|
||||
};
|
||||
|
||||
|
||||
static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
@@ -573,6 +577,23 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
|
||||
gpiod_set_value_cansleep(reset_gpio, 0);
|
||||
}
|
||||
|
||||
static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
int err;
|
||||
|
||||
if (++data->cmd_timeout_cnt < 5)
|
||||
return;
|
||||
|
||||
bt_dev_err(hdev, "Multiple cmd timeouts seen. Resetting usb device.");
|
||||
/* This is not an unbalanced PM reference since the device will reset */
|
||||
err = usb_autopm_get_interface(data->intf);
|
||||
if (!err)
|
||||
usb_queue_reset_device(data->intf);
|
||||
else
|
||||
bt_dev_err(hdev, "Failed usb_autopm_get_interface with %d", err);
|
||||
}
|
||||
|
||||
static inline void btusb_free_frags(struct btusb_data *data)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -1666,14 +1687,15 @@ static void btusb_work(struct work_struct *work)
|
||||
new_alts = data->sco_num;
|
||||
}
|
||||
} else if (data->air_mode == HCI_NOTIFY_ENABLE_SCO_TRANSP) {
|
||||
|
||||
data->usb_alt6_packet_flow = true;
|
||||
|
||||
/* Check if Alt 6 is supported for Transparent audio */
|
||||
if (btusb_find_altsetting(data, 6))
|
||||
if (btusb_find_altsetting(data, 6)) {
|
||||
data->usb_alt6_packet_flow = true;
|
||||
new_alts = 6;
|
||||
else
|
||||
} else if (test_bit(BTUSB_USE_ALT1_FOR_WBS, &data->flags)) {
|
||||
new_alts = 1;
|
||||
} else {
|
||||
bt_dev_err(hdev, "Device does not support ALT setting 6");
|
||||
}
|
||||
}
|
||||
|
||||
if (btusb_switch_alt_setting(hdev, new_alts) < 0)
|
||||
@@ -1720,6 +1742,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
|
||||
{
|
||||
struct hci_rp_read_local_version *rp;
|
||||
struct sk_buff *skb;
|
||||
bool is_fake = false;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
@@ -1739,18 +1762,69 @@ static int btusb_setup_csr(struct hci_dev *hdev)
|
||||
|
||||
rp = (struct hci_rp_read_local_version *)skb->data;
|
||||
|
||||
/* Detect controllers which aren't real CSR ones. */
|
||||
/* Detect a wide host of Chinese controllers that aren't CSR.
|
||||
*
|
||||
* Known fake bcdDevices: 0x0100, 0x0134, 0x1915, 0x2520, 0x7558, 0x8891
|
||||
*
|
||||
* The main thing they have in common is that these are really popular low-cost
|
||||
* options that support newer Bluetooth versions but rely on heavy VID/PID
|
||||
* squatting of this poor old Bluetooth 1.1 device. Even sold as such.
|
||||
*
|
||||
* We detect actual CSR devices by checking that the HCI manufacturer code
|
||||
* is Cambridge Silicon Radio (10) and ensuring that LMP sub-version and
|
||||
* HCI rev values always match. As they both store the firmware number.
|
||||
*/
|
||||
if (le16_to_cpu(rp->manufacturer) != 10 ||
|
||||
le16_to_cpu(rp->lmp_subver) == 0x0c5c) {
|
||||
le16_to_cpu(rp->hci_rev) != le16_to_cpu(rp->lmp_subver))
|
||||
is_fake = true;
|
||||
|
||||
/* Known legit CSR firmware build numbers and their supported BT versions:
|
||||
* - 1.1 (0x1) -> 0x0073, 0x020d, 0x033c, 0x034e
|
||||
* - 1.2 (0x2) -> 0x04d9, 0x0529
|
||||
* - 2.0 (0x3) -> 0x07a6, 0x07ad, 0x0c5c
|
||||
* - 2.1 (0x4) -> 0x149c, 0x1735, 0x1899 (0x1899 is a BlueCore4-External)
|
||||
* - 4.0 (0x6) -> 0x1d86, 0x2031, 0x22bb
|
||||
*
|
||||
* e.g. Real CSR dongles with LMP subversion 0x73 are old enough that
|
||||
* support BT 1.1 only; so it's a dead giveaway when some
|
||||
* third-party BT 4.0 dongle reuses it.
|
||||
*/
|
||||
else if (le16_to_cpu(rp->lmp_subver) <= 0x034e &&
|
||||
le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_1_1)
|
||||
is_fake = true;
|
||||
|
||||
else if (le16_to_cpu(rp->lmp_subver) <= 0x0529 &&
|
||||
le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_1_2)
|
||||
is_fake = true;
|
||||
|
||||
else if (le16_to_cpu(rp->lmp_subver) <= 0x0c5c &&
|
||||
le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_2_0)
|
||||
is_fake = true;
|
||||
|
||||
else if (le16_to_cpu(rp->lmp_subver) <= 0x1899 &&
|
||||
le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_2_1)
|
||||
is_fake = true;
|
||||
|
||||
else if (le16_to_cpu(rp->lmp_subver) <= 0x22bb &&
|
||||
le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_4_0)
|
||||
is_fake = true;
|
||||
|
||||
if (is_fake) {
|
||||
bt_dev_warn(hdev, "CSR: Unbranded CSR clone detected; adding workarounds...");
|
||||
|
||||
/* Generally these clones have big discrepancies between
|
||||
* advertised features and what's actually supported.
|
||||
* Probably will need to be expanded in the future;
|
||||
* without these the controller will lock up.
|
||||
*/
|
||||
set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
|
||||
|
||||
/* Clear the reset quirk since this is not an actual
|
||||
* early Bluetooth 1.1 device from CSR.
|
||||
*/
|
||||
clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
|
||||
|
||||
/* These fake CSR controllers have all a broken
|
||||
* stored link key handling and so just disable it.
|
||||
*/
|
||||
set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
|
||||
clear_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
@@ -2262,45 +2336,25 @@ static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
|
||||
return true;
|
||||
}
|
||||
|
||||
static int btusb_setup_intel_new(struct hci_dev *hdev)
|
||||
static int btusb_intel_download_firmware(struct hci_dev *hdev,
|
||||
struct intel_version *ver,
|
||||
struct intel_boot_params *params)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct intel_version ver;
|
||||
struct intel_boot_params params;
|
||||
const struct firmware *fw;
|
||||
u32 boot_param;
|
||||
char fwname[64];
|
||||
ktime_t calltime, delta, rettime;
|
||||
unsigned long long duration;
|
||||
int err;
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
/* Set the default boot parameter to 0x0 and it is updated to
|
||||
* SKU specific boot parameter after reading Intel_Write_Boot_Params
|
||||
* command while downloading the firmware.
|
||||
*/
|
||||
boot_param = 0x00000000;
|
||||
|
||||
calltime = ktime_get();
|
||||
|
||||
/* Read the Intel version information to determine if the device
|
||||
* is in bootloader mode or if it already has operational firmware
|
||||
* loaded.
|
||||
*/
|
||||
err = btintel_read_version(hdev, &ver);
|
||||
if (err) {
|
||||
bt_dev_err(hdev, "Intel Read version failed (%d)", err);
|
||||
btintel_reset_to_bootloader(hdev);
|
||||
return err;
|
||||
}
|
||||
if (!ver || !params)
|
||||
return -EINVAL;
|
||||
|
||||
/* The hardware platform number has a fixed value of 0x37 and
|
||||
* for now only accept this single value.
|
||||
*/
|
||||
if (ver.hw_platform != 0x37) {
|
||||
if (ver->hw_platform != 0x37) {
|
||||
bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
|
||||
ver.hw_platform);
|
||||
ver->hw_platform);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -2310,7 +2364,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
||||
* This check has been put in place to ensure correct forward
|
||||
* compatibility options when newer hardware variants come along.
|
||||
*/
|
||||
switch (ver.hw_variant) {
|
||||
switch (ver->hw_variant) {
|
||||
case 0x0b: /* SfP */
|
||||
case 0x0c: /* WsP */
|
||||
case 0x11: /* JfP */
|
||||
@@ -2320,11 +2374,11 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
||||
break;
|
||||
default:
|
||||
bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
|
||||
ver.hw_variant);
|
||||
ver->hw_variant);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
btintel_version_info(hdev, &ver);
|
||||
btintel_version_info(hdev, ver);
|
||||
|
||||
/* The firmware variant determines if the device is in bootloader
|
||||
* mode or is running operational firmware. The value 0x06 identifies
|
||||
@@ -2339,25 +2393,25 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
||||
* It is not possible to use the Secure Boot Parameters in this
|
||||
* case since that command is only available in bootloader mode.
|
||||
*/
|
||||
if (ver.fw_variant == 0x23) {
|
||||
if (ver->fw_variant == 0x23) {
|
||||
clear_bit(BTUSB_BOOTLOADER, &data->flags);
|
||||
btintel_check_bdaddr(hdev);
|
||||
goto finish;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the device is not in bootloader mode, then the only possible
|
||||
* choice is to return an error and abort the device initialization.
|
||||
*/
|
||||
if (ver.fw_variant != 0x06) {
|
||||
if (ver->fw_variant != 0x06) {
|
||||
bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
|
||||
ver.fw_variant);
|
||||
ver->fw_variant);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Read the secure boot parameters to identify the operating
|
||||
* details of the bootloader.
|
||||
*/
|
||||
err = btintel_read_boot_params(hdev, ¶ms);
|
||||
err = btintel_read_boot_params(hdev, params);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -2365,16 +2419,16 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
||||
* with a command complete event. If the boot parameters indicate
|
||||
* that this bootloader does not send them, then abort the setup.
|
||||
*/
|
||||
if (params.limited_cce != 0x00) {
|
||||
if (params->limited_cce != 0x00) {
|
||||
bt_dev_err(hdev, "Unsupported Intel firmware loading method (%u)",
|
||||
params.limited_cce);
|
||||
params->limited_cce);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If the OTP has no valid Bluetooth device address, then there will
|
||||
* also be no valid address for the operational firmware.
|
||||
*/
|
||||
if (!bacmp(¶ms.otp_bdaddr, BDADDR_ANY)) {
|
||||
if (!bacmp(¶ms->otp_bdaddr, BDADDR_ANY)) {
|
||||
bt_dev_info(hdev, "No device address configured");
|
||||
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
|
||||
}
|
||||
@@ -2400,7 +2454,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
||||
* ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi.
|
||||
*
|
||||
*/
|
||||
err = btusb_setup_intel_new_get_fw_name(&ver, ¶ms, fwname,
|
||||
err = btusb_setup_intel_new_get_fw_name(ver, params, fwname,
|
||||
sizeof(fwname), "sfi");
|
||||
if (!err) {
|
||||
bt_dev_err(hdev, "Unsupported Intel firmware naming");
|
||||
@@ -2415,16 +2469,6 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
||||
|
||||
bt_dev_info(hdev, "Found device firmware: %s", fwname);
|
||||
|
||||
/* Save the DDC file name for later use to apply once the firmware
|
||||
* downloading is done.
|
||||
*/
|
||||
err = btusb_setup_intel_new_get_fw_name(&ver, ¶ms, fwname,
|
||||
sizeof(fwname), "ddc");
|
||||
if (!err) {
|
||||
bt_dev_err(hdev, "Unsupported Intel firmware naming");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fw->size < 644) {
|
||||
bt_dev_err(hdev, "Invalid size of firmware file (%zu)",
|
||||
fw->size);
|
||||
@@ -2479,18 +2523,58 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
release_firmware(fw);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int btusb_setup_intel_new(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct intel_version ver;
|
||||
struct intel_boot_params params;
|
||||
u32 boot_param;
|
||||
char ddcname[64];
|
||||
ktime_t calltime, delta, rettime;
|
||||
unsigned long long duration;
|
||||
int err;
|
||||
struct intel_debug_features features;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
/* Set the default boot parameter to 0x0 and it is updated to
|
||||
* SKU specific boot parameter after reading Intel_Write_Boot_Params
|
||||
* command while downloading the firmware.
|
||||
*/
|
||||
boot_param = 0x00000000;
|
||||
|
||||
calltime = ktime_get();
|
||||
|
||||
/* Read the Intel version information to determine if the device
|
||||
* is in bootloader mode or if it already has operational firmware
|
||||
* loaded.
|
||||
*/
|
||||
err = btintel_read_version(hdev, &ver);
|
||||
if (err) {
|
||||
bt_dev_err(hdev, "Intel Read version failed (%d)", err);
|
||||
btintel_reset_to_bootloader(hdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = btusb_intel_download_firmware(hdev, &ver, ¶ms);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* controller is already having an operational firmware */
|
||||
if (ver.fw_variant == 0x23)
|
||||
goto finish;
|
||||
|
||||
rettime = ktime_get();
|
||||
delta = ktime_sub(rettime, calltime);
|
||||
duration = (unsigned long long) ktime_to_ns(delta) >> 10;
|
||||
|
||||
bt_dev_info(hdev, "Firmware loaded in %llu usecs", duration);
|
||||
|
||||
done:
|
||||
release_firmware(fw);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
calltime = ktime_get();
|
||||
|
||||
set_bit(BTUSB_BOOTING, &data->flags);
|
||||
@@ -2534,13 +2618,28 @@ done:
|
||||
|
||||
clear_bit(BTUSB_BOOTLOADER, &data->flags);
|
||||
|
||||
/* Once the device is running in operational mode, it needs to apply
|
||||
* the device configuration (DDC) parameters.
|
||||
*
|
||||
* The device can work without DDC parameters, so even if it fails
|
||||
* to load the file, no need to fail the setup.
|
||||
err = btusb_setup_intel_new_get_fw_name(&ver, ¶ms, ddcname,
|
||||
sizeof(ddcname), "ddc");
|
||||
|
||||
if (!err) {
|
||||
bt_dev_err(hdev, "Unsupported Intel firmware naming");
|
||||
} else {
|
||||
/* Once the device is running in operational mode, it needs to
|
||||
* apply the device configuration (DDC) parameters.
|
||||
*
|
||||
* The device can work without DDC parameters, so even if it
|
||||
* fails to load the file, no need to fail the setup.
|
||||
*/
|
||||
btintel_load_ddc_config(hdev, ddcname);
|
||||
}
|
||||
|
||||
/* Read the Intel supported features and if new exception formats
|
||||
* supported, need to load the additional DDC config to enable.
|
||||
*/
|
||||
btintel_load_ddc_config(hdev, fwname);
|
||||
btintel_read_debug_features(hdev, &features);
|
||||
|
||||
/* Set DDC mask for available debug features */
|
||||
btintel_set_debug_features(hdev, &features);
|
||||
|
||||
/* Read the Intel version information after loading the FW */
|
||||
err = btintel_read_version(hdev, &ver);
|
||||
@@ -2925,7 +3024,7 @@ static int btusb_mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
|
||||
const u8 *fw_ptr;
|
||||
size_t fw_size;
|
||||
int err, dlen;
|
||||
u8 flag;
|
||||
u8 flag, param;
|
||||
|
||||
err = request_firmware(&fw, fwname, &hdev->dev);
|
||||
if (err < 0) {
|
||||
@@ -2933,6 +3032,20 @@ static int btusb_mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Power on data RAM the firmware relies on. */
|
||||
param = 1;
|
||||
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
|
||||
wmt_params.flag = 3;
|
||||
wmt_params.dlen = sizeof(param);
|
||||
wmt_params.data = ¶m;
|
||||
wmt_params.status = NULL;
|
||||
|
||||
err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
fw_ptr = fw->data;
|
||||
fw_size = fw->size;
|
||||
|
||||
@@ -3704,6 +3817,9 @@ static bool btusb_prevent_wake(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
|
||||
if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
|
||||
return true;
|
||||
|
||||
return !device_may_wakeup(&data->udev->dev);
|
||||
}
|
||||
|
||||
@@ -3941,10 +4057,20 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
if (id->driver_info & BTUSB_QCA_ROME) {
|
||||
data->setup_on_usb = btusb_setup_qca;
|
||||
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
|
||||
hdev->cmd_timeout = btusb_qca_cmd_timeout;
|
||||
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
||||
btusb_check_needs_reset_resume(intf);
|
||||
}
|
||||
|
||||
if (id->driver_info & BTUSB_AMP) {
|
||||
/* AMP controllers do not support SCO packets */
|
||||
data->isoc = NULL;
|
||||
} else {
|
||||
/* Interface orders are hardcoded in the specification */
|
||||
data->isoc = usb_ifnum_to_if(data->udev, ifnum_base + 1);
|
||||
data->isoc_ifnum = ifnum_base + 1;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_HCIBTUSB_RTL) &&
|
||||
(id->driver_info & BTUSB_REALTEK)) {
|
||||
hdev->setup = btrtl_setup_realtek;
|
||||
@@ -3956,19 +4082,10 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
* (DEVICE_REMOTE_WAKEUP)
|
||||
*/
|
||||
set_bit(BTUSB_WAKEUP_DISABLE, &data->flags);
|
||||
|
||||
err = usb_autopm_get_interface(intf);
|
||||
if (err < 0)
|
||||
goto out_free_dev;
|
||||
}
|
||||
|
||||
if (id->driver_info & BTUSB_AMP) {
|
||||
/* AMP controllers do not support SCO packets */
|
||||
data->isoc = NULL;
|
||||
} else {
|
||||
/* Interface orders are hardcoded in the specification */
|
||||
data->isoc = usb_ifnum_to_if(data->udev, ifnum_base + 1);
|
||||
data->isoc_ifnum = ifnum_base + 1;
|
||||
if (btusb_find_altsetting(data, 1))
|
||||
set_bit(BTUSB_USE_ALT1_FOR_WBS, &data->flags);
|
||||
else
|
||||
bt_dev_err(hdev, "Device does not support ALT setting 1");
|
||||
}
|
||||
|
||||
if (!reset)
|
||||
@@ -4001,11 +4118,13 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
if (bcdDevice < 0x117)
|
||||
set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
|
||||
|
||||
/* Fake CSR devices with broken commands */
|
||||
if (bcdDevice <= 0x100 || bcdDevice == 0x134)
|
||||
hdev->setup = btusb_setup_csr;
|
||||
|
||||
/* This must be set first in case we disable it for fakes */
|
||||
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
||||
|
||||
/* Fake CSR devices with broken commands */
|
||||
if (le16_to_cpu(udev->descriptor.idVendor) == 0x0a12 &&
|
||||
le16_to_cpu(udev->descriptor.idProduct) == 0x0001)
|
||||
hdev->setup = btusb_setup_csr;
|
||||
}
|
||||
|
||||
if (id->driver_info & BTUSB_SNIFFER) {
|
||||
|
||||
@@ -793,7 +793,7 @@ static int h5_serdev_probe(struct serdev_device *serdev)
|
||||
if (!h5)
|
||||
return -ENOMEM;
|
||||
|
||||
set_bit(HCI_UART_RESET_ON_INIT, &h5->serdev_hu.flags);
|
||||
set_bit(HCI_UART_RESET_ON_INIT, &h5->serdev_hu.hdev_flags);
|
||||
|
||||
h5->hu = &h5->serdev_hu;
|
||||
h5->serdev_hu.serdev = serdev;
|
||||
|
||||
@@ -219,7 +219,7 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu)
|
||||
* perfectly safe to always send one.
|
||||
*/
|
||||
BT_DBG("dual wake-up-indication");
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case HCILL_ASLEEP:
|
||||
/* acknowledge device wake up */
|
||||
if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) {
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#define HCI_MAX_IBS_SIZE 10
|
||||
|
||||
#define IBS_WAKE_RETRANS_TIMEOUT_MS 100
|
||||
#define IBS_BTSOC_TX_IDLE_TIMEOUT_MS 40
|
||||
#define IBS_BTSOC_TX_IDLE_TIMEOUT_MS 200
|
||||
#define IBS_HOST_TX_IDLE_TIMEOUT_MS 2000
|
||||
#define CMD_TRANS_TIMEOUT_MS 100
|
||||
#define MEMDUMP_TIMEOUT_MS 8000
|
||||
@@ -72,7 +72,8 @@ enum qca_flags {
|
||||
QCA_DROP_VENDOR_EVENT,
|
||||
QCA_SUSPENDING,
|
||||
QCA_MEMDUMP_COLLECTION,
|
||||
QCA_HW_ERROR_EVENT
|
||||
QCA_HW_ERROR_EVENT,
|
||||
QCA_SSR_TRIGGERED
|
||||
};
|
||||
|
||||
enum qca_capabilities {
|
||||
@@ -289,25 +290,21 @@ static void serial_clock_vote(unsigned long vote, struct hci_uart *hu)
|
||||
case HCI_IBS_TX_VOTE_CLOCK_ON:
|
||||
qca->tx_vote = true;
|
||||
qca->tx_votes_on++;
|
||||
new_vote = true;
|
||||
break;
|
||||
|
||||
case HCI_IBS_RX_VOTE_CLOCK_ON:
|
||||
qca->rx_vote = true;
|
||||
qca->rx_votes_on++;
|
||||
new_vote = true;
|
||||
break;
|
||||
|
||||
case HCI_IBS_TX_VOTE_CLOCK_OFF:
|
||||
qca->tx_vote = false;
|
||||
qca->tx_votes_off++;
|
||||
new_vote = qca->rx_vote | qca->tx_vote;
|
||||
break;
|
||||
|
||||
case HCI_IBS_RX_VOTE_CLOCK_OFF:
|
||||
qca->rx_vote = false;
|
||||
qca->rx_votes_off++;
|
||||
new_vote = qca->rx_vote | qca->tx_vote;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -315,6 +312,8 @@ static void serial_clock_vote(unsigned long vote, struct hci_uart *hu)
|
||||
return;
|
||||
}
|
||||
|
||||
new_vote = qca->rx_vote | qca->tx_vote;
|
||||
|
||||
if (new_vote != old_vote) {
|
||||
if (new_vote)
|
||||
__serial_clock_on(hu->tty);
|
||||
@@ -474,8 +473,6 @@ static void hci_ibs_tx_idle_timeout(struct timer_list *t)
|
||||
|
||||
case HCI_IBS_TX_ASLEEP:
|
||||
case HCI_IBS_TX_WAKING:
|
||||
/* Fall through */
|
||||
|
||||
default:
|
||||
BT_ERR("Spurious timeout tx state %d", qca->tx_ibs_state);
|
||||
break;
|
||||
@@ -518,8 +515,6 @@ static void hci_ibs_wake_retrans_timeout(struct timer_list *t)
|
||||
|
||||
case HCI_IBS_TX_ASLEEP:
|
||||
case HCI_IBS_TX_AWAKE:
|
||||
/* Fall through */
|
||||
|
||||
default:
|
||||
BT_ERR("Spurious timeout tx state %d", qca->tx_ibs_state);
|
||||
break;
|
||||
@@ -837,8 +832,6 @@ static void device_woke_up(struct hci_uart *hu)
|
||||
break;
|
||||
|
||||
case HCI_IBS_TX_ASLEEP:
|
||||
/* Fall through */
|
||||
|
||||
default:
|
||||
BT_ERR("Received HCI_IBS_WAKE_ACK in tx state %d",
|
||||
qca->tx_ibs_state);
|
||||
@@ -862,6 +855,13 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
||||
BT_DBG("hu %p qca enq skb %p tx_ibs_state %d", hu, skb,
|
||||
qca->tx_ibs_state);
|
||||
|
||||
if (test_bit(QCA_SSR_TRIGGERED, &qca->flags)) {
|
||||
/* As SSR is in progress, ignore the packets */
|
||||
bt_dev_dbg(hu->hdev, "SSR is in progress");
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Prepend skb with frame type */
|
||||
memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
|
||||
|
||||
@@ -983,8 +983,11 @@ static void qca_controller_memdump(struct work_struct *work)
|
||||
while ((skb = skb_dequeue(&qca->rx_memdump_q))) {
|
||||
|
||||
mutex_lock(&qca->hci_memdump_lock);
|
||||
/* Skip processing the received packets if timeout detected. */
|
||||
if (qca->memdump_state == QCA_MEMDUMP_TIMEOUT) {
|
||||
/* Skip processing the received packets if timeout detected
|
||||
* or memdump collection completed.
|
||||
*/
|
||||
if (qca->memdump_state == QCA_MEMDUMP_TIMEOUT ||
|
||||
qca->memdump_state == QCA_MEMDUMP_COLLECTED) {
|
||||
mutex_unlock(&qca->hci_memdump_lock);
|
||||
return;
|
||||
}
|
||||
@@ -1128,6 +1131,7 @@ static int qca_controller_memdump_event(struct hci_dev *hdev,
|
||||
struct hci_uart *hu = hci_get_drvdata(hdev);
|
||||
struct qca_data *qca = hu->priv;
|
||||
|
||||
set_bit(QCA_SSR_TRIGGERED, &qca->flags);
|
||||
skb_queue_tail(&qca->rx_memdump_q, skb);
|
||||
queue_work(qca->workqueue, &qca->ctrl_memdump_evt);
|
||||
|
||||
@@ -1485,9 +1489,8 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
|
||||
{
|
||||
struct hci_uart *hu = hci_get_drvdata(hdev);
|
||||
struct qca_data *qca = hu->priv;
|
||||
struct qca_memdump_data *qca_memdump = qca->qca_memdump;
|
||||
char *memdump_buf = NULL;
|
||||
|
||||
set_bit(QCA_SSR_TRIGGERED, &qca->flags);
|
||||
set_bit(QCA_HW_ERROR_EVENT, &qca->flags);
|
||||
bt_dev_info(hdev, "mem_dump_status: %d", qca->memdump_state);
|
||||
|
||||
@@ -1509,19 +1512,23 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
|
||||
qca_wait_for_dump_collection(hdev);
|
||||
}
|
||||
|
||||
mutex_lock(&qca->hci_memdump_lock);
|
||||
if (qca->memdump_state != QCA_MEMDUMP_COLLECTED) {
|
||||
bt_dev_err(hu->hdev, "clearing allocated memory due to memdump timeout");
|
||||
mutex_lock(&qca->hci_memdump_lock);
|
||||
if (qca_memdump)
|
||||
memdump_buf = qca_memdump->memdump_buf_head;
|
||||
vfree(memdump_buf);
|
||||
kfree(qca_memdump);
|
||||
qca->qca_memdump = NULL;
|
||||
if (qca->qca_memdump) {
|
||||
vfree(qca->qca_memdump->memdump_buf_head);
|
||||
kfree(qca->qca_memdump);
|
||||
qca->qca_memdump = NULL;
|
||||
}
|
||||
qca->memdump_state = QCA_MEMDUMP_TIMEOUT;
|
||||
cancel_delayed_work(&qca->ctrl_memdump_timeout);
|
||||
skb_queue_purge(&qca->rx_memdump_q);
|
||||
mutex_unlock(&qca->hci_memdump_lock);
|
||||
}
|
||||
mutex_unlock(&qca->hci_memdump_lock);
|
||||
|
||||
if (qca->memdump_state == QCA_MEMDUMP_TIMEOUT ||
|
||||
qca->memdump_state == QCA_MEMDUMP_COLLECTED) {
|
||||
cancel_work_sync(&qca->ctrl_memdump_evt);
|
||||
skb_queue_purge(&qca->rx_memdump_q);
|
||||
}
|
||||
|
||||
clear_bit(QCA_HW_ERROR_EVENT, &qca->flags);
|
||||
@@ -1532,10 +1539,30 @@ static void qca_cmd_timeout(struct hci_dev *hdev)
|
||||
struct hci_uart *hu = hci_get_drvdata(hdev);
|
||||
struct qca_data *qca = hu->priv;
|
||||
|
||||
if (qca->memdump_state == QCA_MEMDUMP_IDLE)
|
||||
set_bit(QCA_SSR_TRIGGERED, &qca->flags);
|
||||
if (qca->memdump_state == QCA_MEMDUMP_IDLE) {
|
||||
set_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
|
||||
qca_send_crashbuffer(hu);
|
||||
else
|
||||
bt_dev_info(hdev, "Dump collection is in process");
|
||||
qca_wait_for_dump_collection(hdev);
|
||||
} else if (qca->memdump_state == QCA_MEMDUMP_COLLECTING) {
|
||||
/* Let us wait here until memory dump collected or
|
||||
* memory dump timer expired.
|
||||
*/
|
||||
bt_dev_info(hdev, "waiting for dump to complete");
|
||||
qca_wait_for_dump_collection(hdev);
|
||||
}
|
||||
|
||||
mutex_lock(&qca->hci_memdump_lock);
|
||||
if (qca->memdump_state != QCA_MEMDUMP_COLLECTED) {
|
||||
qca->memdump_state = QCA_MEMDUMP_TIMEOUT;
|
||||
if (!test_bit(QCA_HW_ERROR_EVENT, &qca->flags)) {
|
||||
/* Inject hw error event to reset the device
|
||||
* and driver.
|
||||
*/
|
||||
hci_reset_dev(hu->hdev);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&qca->hci_memdump_lock);
|
||||
}
|
||||
|
||||
static int qca_wcn3990_init(struct hci_uart *hu)
|
||||
@@ -1641,11 +1668,15 @@ static int qca_setup(struct hci_uart *hu)
|
||||
bt_dev_info(hdev, "setting up %s",
|
||||
qca_is_wcn399x(soc_type) ? "wcn399x" : "ROME/QCA6390");
|
||||
|
||||
qca->memdump_state = QCA_MEMDUMP_IDLE;
|
||||
|
||||
retry:
|
||||
ret = qca_power_on(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
|
||||
|
||||
if (qca_is_wcn399x(soc_type)) {
|
||||
set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
|
||||
|
||||
@@ -1788,9 +1819,6 @@ static void qca_power_shutdown(struct hci_uart *hu)
|
||||
qca_flush(hu);
|
||||
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
|
||||
|
||||
hu->hdev->hw_error = NULL;
|
||||
hu->hdev->cmd_timeout = NULL;
|
||||
|
||||
/* Non-serdev device usually is powered by external power
|
||||
* and don't need additional action in driver for power down
|
||||
*/
|
||||
@@ -1812,6 +1840,9 @@ static int qca_power_off(struct hci_dev *hdev)
|
||||
struct qca_data *qca = hu->priv;
|
||||
enum qca_btsoc_type soc_type = qca_soc_type(hu);
|
||||
|
||||
hu->hdev->hw_error = NULL;
|
||||
hu->hdev->cmd_timeout = NULL;
|
||||
|
||||
/* Stop sending shutdown command if soc crashes. */
|
||||
if (soc_type != QCA_ROME
|
||||
&& qca->memdump_state == QCA_MEMDUMP_IDLE) {
|
||||
@@ -1819,7 +1850,6 @@ static int qca_power_off(struct hci_dev *hdev)
|
||||
usleep_range(8000, 10000);
|
||||
}
|
||||
|
||||
qca->memdump_state = QCA_MEMDUMP_IDLE;
|
||||
qca_power_shutdown(hu);
|
||||
return 0;
|
||||
}
|
||||
@@ -1962,17 +1992,17 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
||||
}
|
||||
|
||||
qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL);
|
||||
if (!qcadev->susclk) {
|
||||
if (IS_ERR(qcadev->susclk)) {
|
||||
dev_warn(&serdev->dev, "failed to acquire clk\n");
|
||||
} else {
|
||||
err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = clk_prepare_enable(qcadev->susclk);
|
||||
if (err)
|
||||
return err;
|
||||
return PTR_ERR(qcadev->susclk);
|
||||
}
|
||||
err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = clk_prepare_enable(qcadev->susclk);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto);
|
||||
if (err) {
|
||||
@@ -2050,6 +2080,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
|
||||
struct hci_uart *hu = &qcadev->serdev_hu;
|
||||
struct qca_data *qca = hu->priv;
|
||||
unsigned long flags;
|
||||
bool tx_pending = false;
|
||||
int ret = 0;
|
||||
u8 cmd;
|
||||
|
||||
@@ -2068,7 +2099,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
|
||||
switch (qca->tx_ibs_state) {
|
||||
case HCI_IBS_TX_WAKING:
|
||||
del_timer(&qca->wake_retrans_timer);
|
||||
/* Fall through */
|
||||
fallthrough;
|
||||
case HCI_IBS_TX_AWAKE:
|
||||
del_timer(&qca->tx_idle_timer);
|
||||
|
||||
@@ -2083,8 +2114,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
|
||||
|
||||
qca->tx_ibs_state = HCI_IBS_TX_ASLEEP;
|
||||
qca->ibs_sent_slps++;
|
||||
|
||||
qca_wq_serial_tx_clock_vote_off(&qca->ws_tx_vote_off);
|
||||
tx_pending = true;
|
||||
break;
|
||||
|
||||
case HCI_IBS_TX_ASLEEP:
|
||||
@@ -2101,22 +2131,24 @@ static int __maybe_unused qca_suspend(struct device *dev)
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
serdev_device_wait_until_sent(hu->serdev,
|
||||
msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
|
||||
if (tx_pending) {
|
||||
serdev_device_wait_until_sent(hu->serdev,
|
||||
msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
|
||||
serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
|
||||
}
|
||||
|
||||
/* Wait for HCI_IBS_SLEEP_IND sent by device to indicate its Tx is going
|
||||
* to sleep, so that the packet does not wake the system later.
|
||||
*/
|
||||
|
||||
ret = wait_event_interruptible_timeout(qca->suspend_wait_q,
|
||||
qca->rx_ibs_state == HCI_IBS_RX_ASLEEP,
|
||||
msecs_to_jiffies(IBS_BTSOC_TX_IDLE_TIMEOUT_MS));
|
||||
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
|
||||
if (ret == 0)
|
||||
if (ret == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
clear_bit(QCA_SUSPENDING, &qca->flags);
|
||||
|
||||
@@ -355,7 +355,8 @@ void hci_uart_unregister_device(struct hci_uart *hu)
|
||||
struct hci_dev *hdev = hu->hdev;
|
||||
|
||||
clear_bit(HCI_UART_PROTO_READY, &hu->flags);
|
||||
hci_unregister_dev(hdev);
|
||||
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||
hci_unregister_dev(hdev);
|
||||
hci_free_dev(hdev);
|
||||
|
||||
cancel_work_sync(&hu->write_work);
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
#define SD8897_DEFAULT_FW_NAME "mrvl/sd8897_uapsta.bin"
|
||||
#define SD8887_DEFAULT_FW_NAME "mrvl/sd8887_uapsta.bin"
|
||||
#define SD8801_DEFAULT_FW_NAME "mrvl/sd8801_uapsta.bin"
|
||||
#define SD8977_DEFAULT_FW_NAME "mrvl/sd8977_uapsta.bin"
|
||||
#define SD8977_DEFAULT_FW_NAME "mrvl/sdsd8977_combo_v2.bin"
|
||||
#define SD8987_DEFAULT_FW_NAME "mrvl/sd8987_uapsta.bin"
|
||||
#define SD8997_DEFAULT_FW_NAME "mrvl/sd8997_uapsta.bin"
|
||||
#define SD8997_DEFAULT_FW_NAME "mrvl/sdsd8997_combo_v4.bin"
|
||||
|
||||
#define BLOCK_MODE 1
|
||||
#define BYTE_MODE 0
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#define BLUETOOTH_VER_1_1 1
|
||||
#define BLUETOOTH_VER_1_2 2
|
||||
#define BLUETOOTH_VER_2_0 3
|
||||
#define BLUETOOTH_VER_2_1 4
|
||||
#define BLUETOOTH_VER_4_0 6
|
||||
|
||||
/* Reserv for core and drivers use */
|
||||
#define BT_SKB_RESERVE 8
|
||||
@@ -147,6 +149,10 @@ struct bt_voice {
|
||||
#define BT_MODE_LE_FLOWCTL 0x03
|
||||
#define BT_MODE_EXT_FLOWCTL 0x04
|
||||
|
||||
#define BT_PKT_STATUS 16
|
||||
|
||||
#define BT_SCM_PKT_STATUS 0x03
|
||||
|
||||
__printf(1, 2)
|
||||
void bt_info(const char *fmt, ...);
|
||||
__printf(1, 2)
|
||||
@@ -286,6 +292,7 @@ struct bt_sock {
|
||||
struct sock *parent;
|
||||
unsigned long flags;
|
||||
void (*skb_msg_name)(struct sk_buff *, void *, int *);
|
||||
void (*skb_put_cmsg)(struct sk_buff *, struct msghdr *, struct sock *);
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -335,6 +342,10 @@ struct l2cap_ctrl {
|
||||
struct l2cap_chan *chan;
|
||||
};
|
||||
|
||||
struct sco_ctrl {
|
||||
u8 pkt_status;
|
||||
};
|
||||
|
||||
struct hci_dev;
|
||||
|
||||
typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode);
|
||||
@@ -361,6 +372,7 @@ struct bt_skb_cb {
|
||||
u8 incoming:1;
|
||||
union {
|
||||
struct l2cap_ctrl l2cap;
|
||||
struct sco_ctrl sco;
|
||||
struct hci_ctrl hci;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -227,6 +227,17 @@ enum {
|
||||
* supported.
|
||||
*/
|
||||
HCI_QUIRK_VALID_LE_STATES,
|
||||
|
||||
/* When this quirk is set, then erroneous data reporting
|
||||
* is ignored. This is mainly due to the fact that the HCI
|
||||
* Read Default Erroneous Data Reporting command is advertised,
|
||||
* but not supported; these controllers often reply with unknown
|
||||
* command and tend to lock up randomly. Needing a hard reset.
|
||||
*
|
||||
* This quirk can be set before hci_register_dev is called or
|
||||
* during the hdev->setup vendor callback.
|
||||
*/
|
||||
HCI_QUIRK_BROKEN_ERR_DATA_REPORTING,
|
||||
};
|
||||
|
||||
/* HCI device flags */
|
||||
@@ -307,6 +318,7 @@ enum {
|
||||
HCI_FORCE_BREDR_SMP,
|
||||
HCI_FORCE_STATIC_ADDR,
|
||||
HCI_LL_RPA_RESOLUTION,
|
||||
HCI_ENABLE_LL_PRIVACY,
|
||||
HCI_CMD_PENDING,
|
||||
HCI_FORCE_NO_MITM,
|
||||
|
||||
@@ -1637,6 +1649,8 @@ struct hci_rp_le_read_resolv_list_size {
|
||||
|
||||
#define HCI_OP_LE_SET_ADDR_RESOLV_ENABLE 0x202d
|
||||
|
||||
#define HCI_OP_LE_SET_RPA_TIMEOUT 0x202e
|
||||
|
||||
#define HCI_OP_LE_READ_MAX_DATA_LEN 0x202f
|
||||
struct hci_rp_le_read_max_data_len {
|
||||
__u8 status;
|
||||
@@ -2268,8 +2282,10 @@ struct hci_ev_le_conn_complete {
|
||||
#define LE_EXT_ADV_SCAN_RSP 0x0008
|
||||
#define LE_EXT_ADV_LEGACY_PDU 0x0010
|
||||
|
||||
#define ADDR_LE_DEV_PUBLIC 0x00
|
||||
#define ADDR_LE_DEV_RANDOM 0x01
|
||||
#define ADDR_LE_DEV_PUBLIC 0x00
|
||||
#define ADDR_LE_DEV_RANDOM 0x01
|
||||
#define ADDR_LE_DEV_PUBLIC_RESOLVED 0x02
|
||||
#define ADDR_LE_DEV_RANDOM_RESOLVED 0x03
|
||||
|
||||
#define HCI_EV_LE_ADVERTISING_REPORT 0x02
|
||||
struct hci_ev_le_advertising_info {
|
||||
@@ -2516,4 +2532,12 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
|
||||
#define hci_iso_data_len(h) ((h) & 0x3fff)
|
||||
#define hci_iso_data_flags(h) ((h) >> 14)
|
||||
|
||||
/* le24 support */
|
||||
static inline void hci_cpu_to_le24(__u32 val, __u8 dst[3])
|
||||
{
|
||||
dst[0] = val & 0xff;
|
||||
dst[1] = (val & 0xff00) >> 8;
|
||||
dst[2] = (val & 0xff0000) >> 16;
|
||||
}
|
||||
|
||||
#endif /* __HCI_H */
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef __HCI_CORE_H
|
||||
#define __HCI_CORE_H
|
||||
|
||||
#include <linux/idr.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/rculist.h>
|
||||
|
||||
@@ -136,6 +137,23 @@ struct bdaddr_list_with_irk {
|
||||
u8 local_irk[16];
|
||||
};
|
||||
|
||||
struct bdaddr_list_with_flags {
|
||||
struct list_head list;
|
||||
bdaddr_t bdaddr;
|
||||
u8 bdaddr_type;
|
||||
u32 current_flags;
|
||||
};
|
||||
|
||||
enum hci_conn_flags {
|
||||
HCI_CONN_FLAG_REMOTE_WAKEUP,
|
||||
HCI_CONN_FLAG_MAX
|
||||
};
|
||||
|
||||
#define hci_conn_test_flag(nr, flags) ((flags) & (1U << nr))
|
||||
|
||||
/* Make sure number of flags doesn't exceed sizeof(current_flags) */
|
||||
static_assert(HCI_CONN_FLAG_MAX < 32);
|
||||
|
||||
struct bt_uuid {
|
||||
struct list_head list;
|
||||
u8 uuid[16];
|
||||
@@ -220,6 +238,24 @@ struct adv_info {
|
||||
#define HCI_MAX_ADV_INSTANCES 5
|
||||
#define HCI_DEFAULT_ADV_DURATION 2
|
||||
|
||||
struct adv_pattern {
|
||||
struct list_head list;
|
||||
__u8 ad_type;
|
||||
__u8 offset;
|
||||
__u8 length;
|
||||
__u8 value[HCI_MAX_AD_LENGTH];
|
||||
};
|
||||
|
||||
struct adv_monitor {
|
||||
struct list_head patterns;
|
||||
bool active;
|
||||
__u16 handle;
|
||||
};
|
||||
|
||||
#define HCI_MIN_ADV_MONITOR_HANDLE 1
|
||||
#define HCI_MAX_ADV_MONITOR_NUM_HANDLES 32
|
||||
#define HCI_MAX_ADV_MONITOR_NUM_PATTERNS 16
|
||||
|
||||
#define HCI_MAX_SHORT_NAME_LENGTH 10
|
||||
|
||||
/* Min encryption key size to match with SMP */
|
||||
@@ -295,6 +331,14 @@ struct hci_dev {
|
||||
__u8 le_scan_type;
|
||||
__u16 le_scan_interval;
|
||||
__u16 le_scan_window;
|
||||
__u16 le_scan_int_suspend;
|
||||
__u16 le_scan_window_suspend;
|
||||
__u16 le_scan_int_discovery;
|
||||
__u16 le_scan_window_discovery;
|
||||
__u16 le_scan_int_adv_monitor;
|
||||
__u16 le_scan_window_adv_monitor;
|
||||
__u16 le_scan_int_connect;
|
||||
__u16 le_scan_window_connect;
|
||||
__u16 le_conn_min_interval;
|
||||
__u16 le_conn_max_interval;
|
||||
__u16 le_conn_latency;
|
||||
@@ -323,6 +367,17 @@ struct hci_dev {
|
||||
__u16 devid_product;
|
||||
__u16 devid_version;
|
||||
|
||||
__u8 def_page_scan_type;
|
||||
__u16 def_page_scan_int;
|
||||
__u16 def_page_scan_window;
|
||||
__u8 def_inq_scan_type;
|
||||
__u16 def_inq_scan_int;
|
||||
__u16 def_inq_scan_window;
|
||||
__u16 def_br_lsto;
|
||||
__u16 def_page_timeout;
|
||||
__u16 def_multi_adv_rotation_duration;
|
||||
__u16 def_le_autoconnect_timeout;
|
||||
|
||||
__u16 pkt_type;
|
||||
__u16 esco_type;
|
||||
__u16 link_policy;
|
||||
@@ -438,7 +493,6 @@ struct hci_dev {
|
||||
struct list_head mgmt_pending;
|
||||
struct list_head blacklist;
|
||||
struct list_head whitelist;
|
||||
struct list_head wakeable;
|
||||
struct list_head uuids;
|
||||
struct list_head link_keys;
|
||||
struct list_head long_term_keys;
|
||||
@@ -477,6 +531,9 @@ struct hci_dev {
|
||||
__u16 adv_instance_timeout;
|
||||
struct delayed_work adv_instance_expire;
|
||||
|
||||
struct idr adv_monitors_idr;
|
||||
unsigned int adv_monitors_cnt;
|
||||
|
||||
__u8 irk[16];
|
||||
__u32 rpa_timeout;
|
||||
struct delayed_work rpa_expired;
|
||||
@@ -508,6 +565,12 @@ struct hci_dev {
|
||||
|
||||
#define HCI_PHY_HANDLE(handle) (handle & 0xff)
|
||||
|
||||
enum conn_reasons {
|
||||
CONN_REASON_PAIR_DEVICE,
|
||||
CONN_REASON_L2CAP_CHAN,
|
||||
CONN_REASON_SCO_CONNECT,
|
||||
};
|
||||
|
||||
struct hci_conn {
|
||||
struct list_head list;
|
||||
|
||||
@@ -559,6 +622,8 @@ struct hci_conn {
|
||||
__s8 max_tx_power;
|
||||
unsigned long flags;
|
||||
|
||||
enum conn_reasons conn_reason;
|
||||
|
||||
__u32 clock;
|
||||
__u16 clock_accuracy;
|
||||
|
||||
@@ -626,7 +691,7 @@ struct hci_conn_params {
|
||||
|
||||
struct hci_conn *conn;
|
||||
bool explicit_connect;
|
||||
bool wakeable;
|
||||
u32 current_flags;
|
||||
};
|
||||
|
||||
extern struct list_head hci_dev_list;
|
||||
@@ -984,12 +1049,14 @@ struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
|
||||
|
||||
struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 dst_type, u8 sec_level,
|
||||
u16 conn_timeout);
|
||||
u16 conn_timeout,
|
||||
enum conn_reasons conn_reason);
|
||||
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 dst_type, u8 sec_level, u16 conn_timeout,
|
||||
u8 role, bdaddr_t *direct_rpa);
|
||||
struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 sec_level, u8 auth_type);
|
||||
u8 sec_level, u8 auth_type,
|
||||
enum conn_reasons conn_reason);
|
||||
struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
__u16 setting);
|
||||
int hci_conn_check_link_mode(struct hci_conn *conn);
|
||||
@@ -1151,12 +1218,19 @@ struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
|
||||
struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
|
||||
struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type);
|
||||
struct bdaddr_list_with_flags *
|
||||
hci_bdaddr_list_lookup_with_flags(struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type);
|
||||
int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type);
|
||||
int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type, u8 *peer_irk, u8 *local_irk);
|
||||
u8 type, u8 *peer_irk, u8 *local_irk);
|
||||
int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type, u32 flags);
|
||||
int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type);
|
||||
int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type);
|
||||
u8 type);
|
||||
int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type);
|
||||
void hci_bdaddr_list_clear(struct list_head *list);
|
||||
|
||||
struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
|
||||
@@ -1217,6 +1291,12 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
|
||||
int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance);
|
||||
void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired);
|
||||
|
||||
void hci_adv_monitors_clear(struct hci_dev *hdev);
|
||||
void hci_free_adv_monitor(struct adv_monitor *monitor);
|
||||
int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
|
||||
int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle);
|
||||
bool hci_is_adv_monitoring(struct hci_dev *hdev);
|
||||
|
||||
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
|
||||
|
||||
void hci_init_sysfs(struct hci_dev *hdev);
|
||||
@@ -1279,6 +1359,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
|
||||
#define scan_coded(dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_CODED) || \
|
||||
((dev)->le_rx_def_phys & HCI_LE_SET_PHY_CODED))
|
||||
|
||||
/* Use LL Privacy based address resolution if supported */
|
||||
#define use_ll_privacy(dev) ((dev)->le_features[0] & HCI_LE_LL_PRIVACY)
|
||||
|
||||
/* Use ext scanning if set ext scan param and ext scan enable is supported */
|
||||
#define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
|
||||
((dev)->commands[37] & 0x40))
|
||||
@@ -1387,7 +1470,7 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
|
||||
__u8 encrypt;
|
||||
|
||||
if (conn->state == BT_CONFIG) {
|
||||
if (status)
|
||||
if (!status)
|
||||
conn->state = BT_CONNECTED;
|
||||
|
||||
hci_connect_cfm(conn, status);
|
||||
@@ -1402,11 +1485,13 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
|
||||
else
|
||||
encrypt = 0x01;
|
||||
|
||||
if (conn->sec_level == BT_SECURITY_SDP)
|
||||
conn->sec_level = BT_SECURITY_LOW;
|
||||
if (!status) {
|
||||
if (conn->sec_level == BT_SECURITY_SDP)
|
||||
conn->sec_level = BT_SECURITY_LOW;
|
||||
|
||||
if (conn->pending_sec_level > conn->sec_level)
|
||||
conn->sec_level = conn->pending_sec_level;
|
||||
if (conn->pending_sec_level > conn->sec_level)
|
||||
conn->sec_level = conn->pending_sec_level;
|
||||
}
|
||||
|
||||
mutex_lock(&hci_cb_list_lock);
|
||||
list_for_each_entry(cb, &hci_cb_list, list) {
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
#define HCI_TIME_STAMP 3
|
||||
|
||||
/* CMSG flags */
|
||||
#define HCI_CMSG_DIR 0x0001
|
||||
#define HCI_CMSG_TSTAMP 0x0002
|
||||
#define HCI_CMSG_DIR 0x01
|
||||
#define HCI_CMSG_TSTAMP 0x02
|
||||
|
||||
struct sockaddr_hci {
|
||||
sa_family_t hci_family;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user