mirror of
https://github.com/torvalds/linux.git
synced 2025-12-01 07:26:02 +07:00
Merge tag 'for-net-2025-10-24' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - fix corruption in h4_recv_buf() after cleanupCen Zhang (1): - hci_sync: fix race in hci_cmd_sync_dequeue_once - btmtksdio: Add pmctrl handling for BT closed state during reset - Revert "Bluetooth: L2CAP: convert timeouts to secs_to_jiffies()" - rfcomm: fix modem control handling - btintel_pcie: Fix event packet loss issue - ISO: Fix BIS connection dst_type handling - HCI: Fix tracking of advertisement set/instance 0x00 - ISO: Fix another instance of dst_type handling - hci_conn: Fix connection cleanup with BIG with 2 or more BIS - hci_core: Fix tracking of periodic advertisement - MGMT: fix crash in set_mesh_sync and set_mesh_complete * tag 'for-net-2025-10-24' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: rfcomm: fix modem control handling Bluetooth: hci_core: Fix tracking of periodic advertisement Bluetooth: hci_conn: Fix connection cleanup with BIG with 2 or more BIS Bluetooth: fix corruption in h4_recv_buf() after cleanup Bluetooth: btintel_pcie: Fix event packet loss issue Bluetooth: ISO: Fix another instance of dst_type handling Revert "Bluetooth: L2CAP: convert timeouts to secs_to_jiffies()" Bluetooth: MGMT: fix crash in set_mesh_sync and set_mesh_complete Bluetooth: HCI: Fix tracking of advertisement set/instance 0x00 Bluetooth: btmtksdio: Add pmctrl handling for BT closed state during reset Bluetooth: ISO: Fix BIS connection dst_type handling Bluetooth: hci_sync: fix race in hci_cmd_sync_dequeue_once ==================== Link: https://patch.msgid.link/20251024144033.355820-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -41,6 +41,7 @@ struct bpa10x_data {
|
|||||||
struct usb_anchor rx_anchor;
|
struct usb_anchor rx_anchor;
|
||||||
|
|
||||||
struct sk_buff *rx_skb[2];
|
struct sk_buff *rx_skb[2];
|
||||||
|
struct hci_uart hu;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bpa10x_tx_complete(struct urb *urb)
|
static void bpa10x_tx_complete(struct urb *urb)
|
||||||
@@ -96,7 +97,7 @@ static void bpa10x_rx_complete(struct urb *urb)
|
|||||||
if (urb->status == 0) {
|
if (urb->status == 0) {
|
||||||
bool idx = usb_pipebulk(urb->pipe);
|
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->transfer_buffer,
|
||||||
urb->actual_length,
|
urb->actual_length,
|
||||||
bpa10x_recv_pkts,
|
bpa10x_recv_pkts,
|
||||||
@@ -388,6 +389,7 @@ static int bpa10x_probe(struct usb_interface *intf,
|
|||||||
hci_set_drvdata(hdev, data);
|
hci_set_drvdata(hdev, data);
|
||||||
|
|
||||||
data->hdev = hdev;
|
data->hdev = hdev;
|
||||||
|
data->hu.hdev = hdev;
|
||||||
|
|
||||||
SET_HCIDEV_DEV(hdev, &intf->dev);
|
SET_HCIDEV_DEV(hdev, &intf->dev);
|
||||||
|
|
||||||
|
|||||||
@@ -1467,11 +1467,6 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
|
|||||||
if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP1)
|
if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP1)
|
||||||
btintel_pcie_msix_gp1_handler(data);
|
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 */
|
/* For TX */
|
||||||
if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) {
|
if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) {
|
||||||
@@ -1487,6 +1482,12 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
|
|||||||
btintel_pcie_msix_tx_handle(data);
|
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
|
* Before sending the interrupt the HW disables it to prevent a nested
|
||||||
* interrupt. This is done by writing 1 to the corresponding bit in
|
* interrupt. This is done by writing 1 to the corresponding bit in
|
||||||
|
|||||||
@@ -1270,6 +1270,12 @@ static void btmtksdio_reset(struct hci_dev *hdev)
|
|||||||
|
|
||||||
sdio_claim_host(bdev->func);
|
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);
|
sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
|
||||||
skb_queue_purge(&bdev->txq);
|
skb_queue_purge(&bdev->txq);
|
||||||
cancel_work_sync(&bdev->txrx_work);
|
cancel_work_sync(&bdev->txrx_work);
|
||||||
@@ -1285,6 +1291,12 @@ static void btmtksdio_reset(struct hci_dev *hdev)
|
|||||||
goto err;
|
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);
|
clear_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
|
||||||
err:
|
err:
|
||||||
sdio_release_host(bdev->func);
|
sdio_release_host(bdev->func);
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ struct btmtkuart_dev {
|
|||||||
u16 stp_dlen;
|
u16 stp_dlen;
|
||||||
|
|
||||||
const struct btmtkuart_data *data;
|
const struct btmtkuart_data *data;
|
||||||
|
struct hci_uart hu;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define btmtkuart_is_standalone(bdev) \
|
#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;
|
sz_left -= adv;
|
||||||
p_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,
|
sz_h4, mtk_recv_pkts,
|
||||||
ARRAY_SIZE(mtk_recv_pkts));
|
ARRAY_SIZE(mtk_recv_pkts));
|
||||||
if (IS_ERR(bdev->rx_skb)) {
|
if (IS_ERR(bdev->rx_skb)) {
|
||||||
@@ -858,6 +859,7 @@ static int btmtkuart_probe(struct serdev_device *serdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bdev->hdev = hdev;
|
bdev->hdev = hdev;
|
||||||
|
bdev->hu.hdev = hdev;
|
||||||
|
|
||||||
hdev->bus = HCI_UART;
|
hdev->bus = HCI_UART;
|
||||||
hci_set_drvdata(hdev, bdev);
|
hci_set_drvdata(hdev, bdev);
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ struct btnxpuart_dev {
|
|||||||
struct ps_data psdata;
|
struct ps_data psdata;
|
||||||
struct btnxpuart_data *nxp_data;
|
struct btnxpuart_data *nxp_data;
|
||||||
struct reset_control *pdn;
|
struct reset_control *pdn;
|
||||||
|
struct hci_uart hu;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NXP_V1_FW_REQ_PKT 0xa5
|
#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);
|
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));
|
nxp_recv_pkts, ARRAY_SIZE(nxp_recv_pkts));
|
||||||
if (IS_ERR(nxpdev->rx_skb)) {
|
if (IS_ERR(nxpdev->rx_skb)) {
|
||||||
int err = PTR_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);
|
reset_control_deassert(nxpdev->pdn);
|
||||||
|
|
||||||
nxpdev->hdev = hdev;
|
nxpdev->hdev = hdev;
|
||||||
|
nxpdev->hu.hdev = hdev;
|
||||||
|
|
||||||
hdev->bus = HCI_UART;
|
hdev->bus = HCI_UART;
|
||||||
hci_set_drvdata(hdev, nxpdev);
|
hci_set_drvdata(hdev, nxpdev);
|
||||||
|
|||||||
@@ -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))
|
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||||
return -EUNATCH;
|
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,
|
ag6xx_recv_pkts,
|
||||||
ARRAY_SIZE(ag6xx_recv_pkts));
|
ARRAY_SIZE(ag6xx_recv_pkts));
|
||||||
if (IS_ERR(ag6xx->rx_skb)) {
|
if (IS_ERR(ag6xx->rx_skb)) {
|
||||||
|
|||||||
@@ -650,7 +650,7 @@ static int aml_recv(struct hci_uart *hu, const void *data, int count)
|
|||||||
struct aml_data *aml_data = hu->priv;
|
struct aml_data *aml_data = hu->priv;
|
||||||
int err;
|
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,
|
aml_recv_pkts,
|
||||||
ARRAY_SIZE(aml_recv_pkts));
|
ARRAY_SIZE(aml_recv_pkts));
|
||||||
if (IS_ERR(aml_data->rx_skb)) {
|
if (IS_ERR(aml_data->rx_skb)) {
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ static int ath_recv(struct hci_uart *hu, const void *data, int count)
|
|||||||
{
|
{
|
||||||
struct ath_struct *ath = hu->priv;
|
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));
|
ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts));
|
||||||
if (IS_ERR(ath->rx_skb)) {
|
if (IS_ERR(ath->rx_skb)) {
|
||||||
int err = PTR_ERR(ath->rx_skb);
|
int err = PTR_ERR(ath->rx_skb);
|
||||||
|
|||||||
@@ -698,7 +698,7 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count)
|
|||||||
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||||
return -EUNATCH;
|
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));
|
bcm_recv_pkts, ARRAY_SIZE(bcm_recv_pkts));
|
||||||
if (IS_ERR(bcm->rx_skb)) {
|
if (IS_ERR(bcm->rx_skb)) {
|
||||||
int err = PTR_ERR(bcm->rx_skb);
|
int err = PTR_ERR(bcm->rx_skb);
|
||||||
|
|||||||
@@ -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))
|
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||||
return -EUNATCH;
|
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));
|
h4_recv_pkts, ARRAY_SIZE(h4_recv_pkts));
|
||||||
if (IS_ERR(h4->rx_skb)) {
|
if (IS_ERR(h4->rx_skb)) {
|
||||||
int err = PTR_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);
|
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 unsigned char *buffer, int count,
|
||||||
const struct h4_recv_pkt *pkts, int pkts_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;
|
u8 alignment = hu->alignment ? hu->alignment : 1;
|
||||||
|
struct hci_dev *hdev = hu->hdev;
|
||||||
|
|
||||||
/* Check for error from previous call */
|
/* Check for error from previous call */
|
||||||
if (IS_ERR(skb))
|
if (IS_ERR(skb))
|
||||||
|
|||||||
@@ -972,7 +972,7 @@ static int intel_recv(struct hci_uart *hu, const void *data, int count)
|
|||||||
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||||
return -EUNATCH;
|
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,
|
intel_recv_pkts,
|
||||||
ARRAY_SIZE(intel_recv_pkts));
|
ARRAY_SIZE(intel_recv_pkts));
|
||||||
if (IS_ERR(intel->rx_skb)) {
|
if (IS_ERR(intel->rx_skb)) {
|
||||||
|
|||||||
@@ -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))
|
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||||
return -EUNATCH;
|
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));
|
ll_recv_pkts, ARRAY_SIZE(ll_recv_pkts));
|
||||||
if (IS_ERR(ll->rx_skb)) {
|
if (IS_ERR(ll->rx_skb)) {
|
||||||
int err = PTR_ERR(ll->rx_skb);
|
int err = PTR_ERR(ll->rx_skb);
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ static int mrvl_recv(struct hci_uart *hu, const void *data, int count)
|
|||||||
!test_bit(STATE_FW_LOADED, &mrvl->flags))
|
!test_bit(STATE_FW_LOADED, &mrvl->flags))
|
||||||
return count;
|
return count;
|
||||||
|
|
||||||
mrvl->rx_skb = h4_recv_buf(hu->hdev, mrvl->rx_skb, data, count,
|
mrvl->rx_skb = h4_recv_buf(hu, mrvl->rx_skb, data, count,
|
||||||
mrvl_recv_pkts,
|
mrvl_recv_pkts,
|
||||||
ARRAY_SIZE(mrvl_recv_pkts));
|
ARRAY_SIZE(mrvl_recv_pkts));
|
||||||
if (IS_ERR(mrvl->rx_skb)) {
|
if (IS_ERR(mrvl->rx_skb)) {
|
||||||
|
|||||||
@@ -624,7 +624,7 @@ static int nokia_recv(struct hci_uart *hu, const void *data, int count)
|
|||||||
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||||
return -EUNATCH;
|
return -EUNATCH;
|
||||||
|
|
||||||
btdev->rx_skb = h4_recv_buf(hu->hdev, btdev->rx_skb, data, count,
|
btdev->rx_skb = h4_recv_buf(hu, btdev->rx_skb, data, count,
|
||||||
nokia_recv_pkts, ARRAY_SIZE(nokia_recv_pkts));
|
nokia_recv_pkts, ARRAY_SIZE(nokia_recv_pkts));
|
||||||
if (IS_ERR(btdev->rx_skb)) {
|
if (IS_ERR(btdev->rx_skb)) {
|
||||||
err = PTR_ERR(btdev->rx_skb);
|
err = PTR_ERR(btdev->rx_skb);
|
||||||
|
|||||||
@@ -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))
|
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||||
return -EUNATCH;
|
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));
|
qca_recv_pkts, ARRAY_SIZE(qca_recv_pkts));
|
||||||
if (IS_ERR(qca->rx_skb)) {
|
if (IS_ERR(qca->rx_skb)) {
|
||||||
int err = PTR_ERR(qca->rx_skb);
|
int err = PTR_ERR(qca->rx_skb);
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ struct h4_recv_pkt {
|
|||||||
int h4_init(void);
|
int h4_init(void);
|
||||||
int h4_deinit(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 unsigned char *buffer, int count,
|
||||||
const struct h4_recv_pkt *pkts, int pkts_count);
|
const struct h4_recv_pkt *pkts, int pkts_count);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -434,6 +434,7 @@ enum {
|
|||||||
HCI_USER_CHANNEL,
|
HCI_USER_CHANNEL,
|
||||||
HCI_EXT_CONFIGURED,
|
HCI_EXT_CONFIGURED,
|
||||||
HCI_LE_ADV,
|
HCI_LE_ADV,
|
||||||
|
HCI_LE_ADV_0,
|
||||||
HCI_LE_PER_ADV,
|
HCI_LE_PER_ADV,
|
||||||
HCI_LE_SCAN,
|
HCI_LE_SCAN,
|
||||||
HCI_SSP_ENABLED,
|
HCI_SSP_ENABLED,
|
||||||
|
|||||||
@@ -244,6 +244,7 @@ struct adv_info {
|
|||||||
bool enabled;
|
bool enabled;
|
||||||
bool pending;
|
bool pending;
|
||||||
bool periodic;
|
bool periodic;
|
||||||
|
bool periodic_enabled;
|
||||||
__u8 mesh;
|
__u8 mesh;
|
||||||
__u8 instance;
|
__u8 instance;
|
||||||
__u8 handle;
|
__u8 handle;
|
||||||
|
|||||||
@@ -38,8 +38,8 @@
|
|||||||
#define L2CAP_DEFAULT_TX_WINDOW 63
|
#define L2CAP_DEFAULT_TX_WINDOW 63
|
||||||
#define L2CAP_DEFAULT_EXT_WINDOW 0x3FFF
|
#define L2CAP_DEFAULT_EXT_WINDOW 0x3FFF
|
||||||
#define L2CAP_DEFAULT_MAX_TX 3
|
#define L2CAP_DEFAULT_MAX_TX 3
|
||||||
#define L2CAP_DEFAULT_RETRANS_TO 2 /* seconds */
|
#define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */
|
||||||
#define L2CAP_DEFAULT_MONITOR_TO 12 /* seconds */
|
#define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */
|
||||||
#define L2CAP_DEFAULT_MAX_PDU_SIZE 1492 /* Sized for AMP packet */
|
#define L2CAP_DEFAULT_MAX_PDU_SIZE 1492 /* Sized for AMP packet */
|
||||||
#define L2CAP_DEFAULT_ACK_TO 200
|
#define L2CAP_DEFAULT_ACK_TO 200
|
||||||
#define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF
|
#define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF
|
||||||
|
|||||||
@@ -853,7 +853,7 @@ struct mgmt_cp_set_mesh {
|
|||||||
__le16 window;
|
__le16 window;
|
||||||
__le16 period;
|
__le16 period;
|
||||||
__u8 num_ad_types;
|
__u8 num_ad_types;
|
||||||
__u8 ad_types[];
|
__u8 ad_types[] __counted_by(num_ad_types);
|
||||||
} __packed;
|
} __packed;
|
||||||
#define MGMT_SET_MESH_RECEIVER_SIZE 6
|
#define MGMT_SET_MESH_RECEIVER_SIZE 6
|
||||||
|
|
||||||
|
|||||||
@@ -843,6 +843,13 @@ static void bis_cleanup(struct hci_conn *conn)
|
|||||||
if (bis)
|
if (bis)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bis = hci_conn_hash_lookup_big_state(hdev,
|
||||||
|
conn->iso_qos.bcast.big,
|
||||||
|
BT_OPEN,
|
||||||
|
HCI_ROLE_MASTER);
|
||||||
|
if (bis)
|
||||||
|
return;
|
||||||
|
|
||||||
hci_le_terminate_big(hdev, conn);
|
hci_le_terminate_big(hdev, conn);
|
||||||
} else {
|
} else {
|
||||||
hci_le_big_terminate(hdev, conn->iso_qos.bcast.big,
|
hci_le_big_terminate(hdev, conn->iso_qos.bcast.big,
|
||||||
|
|||||||
@@ -1607,8 +1607,10 @@ static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
|
|||||||
|
|
||||||
hci_dev_set_flag(hdev, HCI_LE_ADV);
|
hci_dev_set_flag(hdev, HCI_LE_ADV);
|
||||||
|
|
||||||
if (adv && !adv->periodic)
|
if (adv)
|
||||||
adv->enabled = true;
|
adv->enabled = true;
|
||||||
|
else if (!set->handle)
|
||||||
|
hci_dev_set_flag(hdev, HCI_LE_ADV_0);
|
||||||
|
|
||||||
conn = hci_lookup_le_connect(hdev);
|
conn = hci_lookup_le_connect(hdev);
|
||||||
if (conn)
|
if (conn)
|
||||||
@@ -1619,6 +1621,8 @@ static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
|
|||||||
if (cp->num_of_sets) {
|
if (cp->num_of_sets) {
|
||||||
if (adv)
|
if (adv)
|
||||||
adv->enabled = false;
|
adv->enabled = false;
|
||||||
|
else if (!set->handle)
|
||||||
|
hci_dev_clear_flag(hdev, HCI_LE_ADV_0);
|
||||||
|
|
||||||
/* If just one instance was disabled check if there are
|
/* If just one instance was disabled check if there are
|
||||||
* any other instance enabled before clearing HCI_LE_ADV
|
* any other instance enabled before clearing HCI_LE_ADV
|
||||||
@@ -3959,8 +3963,11 @@ static u8 hci_cc_le_set_per_adv_enable(struct hci_dev *hdev, void *data,
|
|||||||
hci_dev_set_flag(hdev, HCI_LE_PER_ADV);
|
hci_dev_set_flag(hdev, HCI_LE_PER_ADV);
|
||||||
|
|
||||||
if (adv)
|
if (adv)
|
||||||
adv->enabled = true;
|
adv->periodic_enabled = true;
|
||||||
} else {
|
} else {
|
||||||
|
if (adv)
|
||||||
|
adv->periodic_enabled = false;
|
||||||
|
|
||||||
/* If just one instance was disabled check if there are
|
/* If just one instance was disabled check if there are
|
||||||
* any other instance enabled before clearing HCI_LE_PER_ADV.
|
* any other instance enabled before clearing HCI_LE_PER_ADV.
|
||||||
* The current periodic adv instance will be marked as
|
* The current periodic adv instance will be marked as
|
||||||
|
|||||||
@@ -863,11 +863,17 @@ bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev,
|
|||||||
{
|
{
|
||||||
struct hci_cmd_sync_work_entry *entry;
|
struct hci_cmd_sync_work_entry *entry;
|
||||||
|
|
||||||
entry = hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
|
mutex_lock(&hdev->cmd_sync_work_lock);
|
||||||
if (!entry)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
hci_cmd_sync_cancel_entry(hdev, entry);
|
entry = _hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
|
||||||
|
if (!entry) {
|
||||||
|
mutex_unlock(&hdev->cmd_sync_work_lock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
|
||||||
|
|
||||||
|
mutex_unlock(&hdev->cmd_sync_work_lock);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1601,7 +1607,7 @@ int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
|
|||||||
|
|
||||||
/* If periodic advertising already disabled there is nothing to do. */
|
/* If periodic advertising already disabled there is nothing to do. */
|
||||||
adv = hci_find_adv_instance(hdev, instance);
|
adv = hci_find_adv_instance(hdev, instance);
|
||||||
if (!adv || !adv->periodic || !adv->enabled)
|
if (!adv || !adv->periodic_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memset(&cp, 0, sizeof(cp));
|
memset(&cp, 0, sizeof(cp));
|
||||||
@@ -1666,7 +1672,7 @@ static int hci_enable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
|
|||||||
|
|
||||||
/* If periodic advertising already enabled there is nothing to do. */
|
/* If periodic advertising already enabled there is nothing to do. */
|
||||||
adv = hci_find_adv_instance(hdev, instance);
|
adv = hci_find_adv_instance(hdev, instance);
|
||||||
if (adv && adv->periodic && adv->enabled)
|
if (adv && adv->periodic_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memset(&cp, 0, sizeof(cp));
|
memset(&cp, 0, sizeof(cp));
|
||||||
@@ -2600,9 +2606,8 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev)
|
|||||||
/* If current advertising instance is set to instance 0x00
|
/* If current advertising instance is set to instance 0x00
|
||||||
* then we need to re-enable it.
|
* then we need to re-enable it.
|
||||||
*/
|
*/
|
||||||
if (!hdev->cur_adv_instance)
|
if (hci_dev_test_and_clear_flag(hdev, HCI_LE_ADV_0))
|
||||||
err = hci_enable_ext_advertising_sync(hdev,
|
err = hci_enable_ext_advertising_sync(hdev, 0x00);
|
||||||
hdev->cur_adv_instance);
|
|
||||||
} else {
|
} else {
|
||||||
/* Schedule for most recent instance to be restarted and begin
|
/* Schedule for most recent instance to be restarted and begin
|
||||||
* the software rotation loop
|
* the software rotation loop
|
||||||
|
|||||||
@@ -2032,7 +2032,7 @@ static void iso_conn_ready(struct iso_conn *conn)
|
|||||||
*/
|
*/
|
||||||
if (!bacmp(&hcon->dst, BDADDR_ANY)) {
|
if (!bacmp(&hcon->dst, BDADDR_ANY)) {
|
||||||
bacpy(&hcon->dst, &iso_pi(parent)->dst);
|
bacpy(&hcon->dst, &iso_pi(parent)->dst);
|
||||||
hcon->dst_type = iso_pi(parent)->dst_type;
|
hcon->dst_type = le_addr_type(iso_pi(parent)->dst_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
|
if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
|
||||||
@@ -2046,7 +2046,13 @@ static void iso_conn_ready(struct iso_conn *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bacpy(&iso_pi(sk)->dst, &hcon->dst);
|
bacpy(&iso_pi(sk)->dst, &hcon->dst);
|
||||||
iso_pi(sk)->dst_type = hcon->dst_type;
|
|
||||||
|
/* Convert from HCI to three-value type */
|
||||||
|
if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
|
||||||
|
iso_pi(sk)->dst_type = BDADDR_LE_PUBLIC;
|
||||||
|
else
|
||||||
|
iso_pi(sk)->dst_type = BDADDR_LE_RANDOM;
|
||||||
|
|
||||||
iso_pi(sk)->sync_handle = iso_pi(parent)->sync_handle;
|
iso_pi(sk)->sync_handle = iso_pi(parent)->sync_handle;
|
||||||
memcpy(iso_pi(sk)->base, iso_pi(parent)->base, iso_pi(parent)->base_len);
|
memcpy(iso_pi(sk)->base, iso_pi(parent)->base, iso_pi(parent)->base_len);
|
||||||
iso_pi(sk)->base_len = iso_pi(parent)->base_len;
|
iso_pi(sk)->base_len = iso_pi(parent)->base_len;
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ static void __set_retrans_timer(struct l2cap_chan *chan)
|
|||||||
if (!delayed_work_pending(&chan->monitor_timer) &&
|
if (!delayed_work_pending(&chan->monitor_timer) &&
|
||||||
chan->retrans_timeout) {
|
chan->retrans_timeout) {
|
||||||
l2cap_set_timer(chan, &chan->retrans_timer,
|
l2cap_set_timer(chan, &chan->retrans_timer,
|
||||||
secs_to_jiffies(chan->retrans_timeout));
|
msecs_to_jiffies(chan->retrans_timeout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,7 +291,7 @@ static void __set_monitor_timer(struct l2cap_chan *chan)
|
|||||||
__clear_retrans_timer(chan);
|
__clear_retrans_timer(chan);
|
||||||
if (chan->monitor_timeout) {
|
if (chan->monitor_timeout) {
|
||||||
l2cap_set_timer(chan, &chan->monitor_timer,
|
l2cap_set_timer(chan, &chan->monitor_timer,
|
||||||
secs_to_jiffies(chan->monitor_timeout));
|
msecs_to_jiffies(chan->monitor_timeout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2175,19 +2175,24 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err)
|
|||||||
sk = cmd->sk;
|
sk = cmd->sk;
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
|
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||||
|
status);
|
||||||
mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true,
|
mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true,
|
||||||
cmd_status_rsp, &status);
|
cmd_status_rsp, &status);
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
mgmt_pending_remove(cmd);
|
|
||||||
mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, 0, NULL, 0);
|
mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, 0, NULL, 0);
|
||||||
|
|
||||||
|
done:
|
||||||
|
mgmt_pending_free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_mesh_sync(struct hci_dev *hdev, void *data)
|
static int set_mesh_sync(struct hci_dev *hdev, void *data)
|
||||||
{
|
{
|
||||||
struct mgmt_pending_cmd *cmd = data;
|
struct mgmt_pending_cmd *cmd = data;
|
||||||
struct mgmt_cp_set_mesh cp;
|
DEFINE_FLEX(struct mgmt_cp_set_mesh, cp, ad_types, num_ad_types,
|
||||||
|
sizeof(hdev->mesh_ad_types));
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
mutex_lock(&hdev->mgmt_pending_lock);
|
mutex_lock(&hdev->mgmt_pending_lock);
|
||||||
@@ -2197,27 +2202,26 @@ static int set_mesh_sync(struct hci_dev *hdev, void *data)
|
|||||||
return -ECANCELED;
|
return -ECANCELED;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&cp, cmd->param, sizeof(cp));
|
len = cmd->param_len;
|
||||||
|
memcpy(cp, cmd->param, min(__struct_size(cp), len));
|
||||||
|
|
||||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||||
|
|
||||||
len = cmd->param_len;
|
|
||||||
|
|
||||||
memset(hdev->mesh_ad_types, 0, sizeof(hdev->mesh_ad_types));
|
memset(hdev->mesh_ad_types, 0, sizeof(hdev->mesh_ad_types));
|
||||||
|
|
||||||
if (cp.enable)
|
if (cp->enable)
|
||||||
hci_dev_set_flag(hdev, HCI_MESH);
|
hci_dev_set_flag(hdev, HCI_MESH);
|
||||||
else
|
else
|
||||||
hci_dev_clear_flag(hdev, HCI_MESH);
|
hci_dev_clear_flag(hdev, HCI_MESH);
|
||||||
|
|
||||||
hdev->le_scan_interval = __le16_to_cpu(cp.period);
|
hdev->le_scan_interval = __le16_to_cpu(cp->period);
|
||||||
hdev->le_scan_window = __le16_to_cpu(cp.window);
|
hdev->le_scan_window = __le16_to_cpu(cp->window);
|
||||||
|
|
||||||
len -= sizeof(cp);
|
len -= sizeof(struct mgmt_cp_set_mesh);
|
||||||
|
|
||||||
/* If filters don't fit, forward all adv pkts */
|
/* If filters don't fit, forward all adv pkts */
|
||||||
if (len <= sizeof(hdev->mesh_ad_types))
|
if (len <= sizeof(hdev->mesh_ad_types))
|
||||||
memcpy(hdev->mesh_ad_types, cp.ad_types, len);
|
memcpy(hdev->mesh_ad_types, cp->ad_types, len);
|
||||||
|
|
||||||
hci_update_passive_scan_sync(hdev);
|
hci_update_passive_scan_sync(hdev);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -643,8 +643,8 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
|
|||||||
tty_port_tty_hangup(&dev->port, true);
|
tty_port_tty_hangup(&dev->port, true);
|
||||||
|
|
||||||
dev->modem_status =
|
dev->modem_status =
|
||||||
((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
|
((v24_sig & RFCOMM_V24_RTC) ? TIOCM_DSR : 0) |
|
||||||
((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
|
((v24_sig & RFCOMM_V24_RTR) ? TIOCM_CTS : 0) |
|
||||||
((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
|
((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
|
||||||
((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
|
((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
|
||||||
}
|
}
|
||||||
@@ -1055,10 +1055,14 @@ static void rfcomm_tty_hangup(struct tty_struct *tty)
|
|||||||
static int rfcomm_tty_tiocmget(struct tty_struct *tty)
|
static int rfcomm_tty_tiocmget(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
struct rfcomm_dev *dev = tty->driver_data;
|
struct rfcomm_dev *dev = tty->driver_data;
|
||||||
|
struct rfcomm_dlc *dlc = dev->dlc;
|
||||||
|
u8 v24_sig;
|
||||||
|
|
||||||
BT_DBG("tty %p dev %p", tty, dev);
|
BT_DBG("tty %p dev %p", tty, dev);
|
||||||
|
|
||||||
return dev->modem_status;
|
rfcomm_dlc_get_modem_status(dlc, &v24_sig);
|
||||||
|
|
||||||
|
return (v24_sig & (TIOCM_DTR | TIOCM_RTS)) | dev->modem_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
|
static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
|
||||||
@@ -1071,23 +1075,15 @@ static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigne
|
|||||||
|
|
||||||
rfcomm_dlc_get_modem_status(dlc, &v24_sig);
|
rfcomm_dlc_get_modem_status(dlc, &v24_sig);
|
||||||
|
|
||||||
if (set & TIOCM_DSR || set & TIOCM_DTR)
|
if (set & TIOCM_DTR)
|
||||||
v24_sig |= RFCOMM_V24_RTC;
|
v24_sig |= RFCOMM_V24_RTC;
|
||||||
if (set & TIOCM_RTS || set & TIOCM_CTS)
|
if (set & TIOCM_RTS)
|
||||||
v24_sig |= RFCOMM_V24_RTR;
|
v24_sig |= RFCOMM_V24_RTR;
|
||||||
if (set & TIOCM_RI)
|
|
||||||
v24_sig |= RFCOMM_V24_IC;
|
|
||||||
if (set & TIOCM_CD)
|
|
||||||
v24_sig |= RFCOMM_V24_DV;
|
|
||||||
|
|
||||||
if (clear & TIOCM_DSR || clear & TIOCM_DTR)
|
if (clear & TIOCM_DTR)
|
||||||
v24_sig &= ~RFCOMM_V24_RTC;
|
v24_sig &= ~RFCOMM_V24_RTC;
|
||||||
if (clear & TIOCM_RTS || clear & TIOCM_CTS)
|
if (clear & TIOCM_RTS)
|
||||||
v24_sig &= ~RFCOMM_V24_RTR;
|
v24_sig &= ~RFCOMM_V24_RTR;
|
||||||
if (clear & TIOCM_RI)
|
|
||||||
v24_sig &= ~RFCOMM_V24_IC;
|
|
||||||
if (clear & TIOCM_CD)
|
|
||||||
v24_sig &= ~RFCOMM_V24_DV;
|
|
||||||
|
|
||||||
rfcomm_dlc_set_modem_status(dlc, v24_sig);
|
rfcomm_dlc_set_modem_status(dlc, v24_sig);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user