mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 12:35:52 +02:00
bluetooth-next pull request for net-next:
core: - L2CAP: Add support for setting BT_PHY - HCI: Add LE Channel Sounding HCI Command/event structures - hci_conn: Set link_policy on incoming ACL connections - MGMT: Add idle_timeout to configurable system parameters drivers: - btusb: Add support for MediaTek7920 0489:e158 - btusb: Add device ID for Realtek RTL8761BU - btusb: Reject autosuspend if discovery is active - btusb: Add new VID/PID for RTL8852CE - btusb: Add USB ID 0489:e112 for Realtek 8851BE - dt-bindings: qcom: Split to separate schema - btqca: Add WCN6855 firmware priority selection feature -----BEGIN PGP SIGNATURE----- iQJNBAABCgA3FiEE7E6oRXp8w05ovYr/9JCA4xAyCykFAml7xEwZHGx1aXoudm9u LmRlbnR6QGludGVsLmNvbQAKCRD0kIDjEDILKZAnEACBXUlzYey49zIwVh/nExcS 0HD1qDl7i6RpgeDeTGbGNiHk5IiS79GJbFar7KbxdbWHozPos21kAu0tZxDsC2w+ KahxU1n3xHucO3YlXJh05W1SM3FLcHKM6o6Ib1+oycNAbWvfPMaYcG+vM34PBncM qoTeb8U8f3nI6P92SSJxIr1Dnj4pzOuNifWZoPP/51jRHeZdqICdFSvrK9OsgQZi dVyg+NIVgJav2q8BwnU8TAN6dmES9fnMEP8RDKDXH5IyKNG5eUdUEbceVj51+IUj t7B7XyPmYhIR37CKidxKh09HXNSZ+IGKiIX3c9Jl0PoUKzyisiXp6tQxcp0Vo54+ IU9kZTMrI3MsWFh42PcHy1WBmBUxoHuy0y0+dMQ6xD1vOKI2z6yt07gxd4LIRZgZ QTwrUExrteobnxhqWjiDrtLf4ZqRg57Vgyu4Y0klf60MaHFiKoxVOLT9OCZ0mxsA fgoonLSvBJtRhl7lEUO/+p1enDvywVeZD9ygPFFuDSbM1TCOL116BVk5sHWZdQjD K5i2zr80b4YYiMrkX+7bHbxgX/aEVeMQHFkyvSutrqQql8oCmsqB4rIx0LKPtZX+ lbixt6dR7MeCmcRgtPEmKUbG3vnt+1+NYziuAc1PtqvSxv4vfYjUOP/yZ0dpmsGk RPEObC9dq1rv564g586Dvw== =I+rw -----END PGP SIGNATURE----- Merge tag 'for-net-next-2026-01-29' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next Luiz Augusto von Dentz says: ==================== bluetooth-next pull request for net-next: core: - L2CAP: Add support for setting BT_PHY - HCI: Add LE Channel Sounding HCI Command/event structures - hci_conn: Set link_policy on incoming ACL connections - MGMT: Add idle_timeout to configurable system parameters drivers: - btusb: Add support for MediaTek7920 0489:e158 - btusb: Add device ID for Realtek RTL8761BU - btusb: Reject autosuspend if discovery is active - btusb: Add new VID/PID for RTL8852CE - btusb: Add USB ID 0489:e112 for Realtek 8851BE - dt-bindings: qcom: Split to separate schema - btqca: Add WCN6855 firmware priority selection feature * tag 'for-net-next-2026-01-29' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next: (40 commits) Bluetooth: hci_qca: Enable HFP hardware offload for WCN6855 and WCN7850 Bluetooth: hci_qca: Refactor HFP hardware offload capability handling Bluetooth: btusb: Add USB ID 7392:e611 for Edimax EW-7611UXB Bluetooth: L2CAP: Fix not tracking outstanding TX ident Bluetooth: MGMT: Fix memory leak in set_ssp_complete Bluetooth: hci_uart: fix null-ptr-deref in hci_uart_write_work Bluetooth: btusb: Remove duplicate entry for 0x13d3/0x3618 Bluetooth: btusb: Add device ID for Realtek RTL8761BU Bluetooth: btintel: Remove unneeded CONFIG_PM* #ifdef's Bluetooth: btnxpuart: Remove unneeded CONFIG_PM ifdef Bluetooth: btusb: Add new VID/PID for RTL8852CE Bluetooth: btintel_pcie: Remove unnecessary check before kfree_skb() Bluetooth: btusb: Reject autosuspend if discovery is active Bluetooth: hci_core: Export hci_discovery_active Bluetooth: btusb: Use pm_ptr instead of #ifdef CONFIG_PM dt-bindings: bluetooth: qcom,wcn7850-bt: Deprecate old supplies dt-bindings: bluetooth: qcom,wcn7850-bt: Split to separate schema dt-bindings: bluetooth: qcom,wcn6855-bt: Deprecate old supplies dt-bindings: bluetooth: qcom,wcn6855-bt: Split to separate schema dt-bindings: bluetooth: qcom,wcn6750-bt: Deprecate old supplies ... ==================== Link: https://patch.msgid.link/20260129203610.963067-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
7227e984c3
|
|
@ -0,0 +1,25 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qcom,bluetooth-common.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Bluetooth Common Properties
|
||||
|
||||
maintainers:
|
||||
- Balakrishna Godavarthi <quic_bgodavar@quicinc.com>
|
||||
- Rocky Liao <quic_rjliao@quicinc.com>
|
||||
|
||||
properties:
|
||||
firmware-name:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: specify the name of nvm firmware to load
|
||||
- description: specify the name of rampatch firmware to load
|
||||
|
||||
qcom,local-bd-address-broken:
|
||||
type: boolean
|
||||
description:
|
||||
boot firmware is incorrectly passing the address in big-endian order
|
||||
|
||||
additionalProperties: true
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qcom,qca2066-bt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QCA2006 Bluetooth
|
||||
|
||||
maintainers:
|
||||
- Balakrishna Godavarthi <quic_bgodavar@quicinc.com>
|
||||
- Rocky Liao <quic_rjliao@quicinc.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,qca2066-bt
|
||||
- qcom,qca6174-bt
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: External low-power 32.768 kHz clock input
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- enable-gpios
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
- $ref: qcom,bluetooth-common.yaml
|
||||
- $ref: /schemas/serial/serial-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
serial {
|
||||
bluetooth {
|
||||
compatible = "qcom,qca6174-bt";
|
||||
clocks = <&divclk4>;
|
||||
enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>;
|
||||
firmware-name = "nvm_00440302.bin";
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qcom,qca6390-bt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QCA6390 Bluetooth
|
||||
|
||||
maintainers:
|
||||
- Balakrishna Godavarthi <quic_bgodavar@quicinc.com>
|
||||
- Rocky Liao <quic_rjliao@quicinc.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,qca6390-bt
|
||||
|
||||
vddaon-supply:
|
||||
description: VDD_AON supply regulator handle
|
||||
|
||||
vddbtcmx-supply:
|
||||
description: VDD_BT_CMX supply regulator handle
|
||||
|
||||
vddrfa0p8-supply:
|
||||
description: VDD_RFA_0P8 supply regulator handle
|
||||
|
||||
vddrfa1p2-supply:
|
||||
description: VDD_RFA_1P2 supply regulator handle
|
||||
|
||||
vddrfa1p7-supply:
|
||||
description: VDD_RFA_1P7 supply regulator handle
|
||||
|
||||
vddrfacmn-supply:
|
||||
description: VDD_RFA_CMN supply regulator handle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- vddaon-supply
|
||||
- vddbtcmx-supply
|
||||
- vddrfa0p8-supply
|
||||
- vddrfa1p2-supply
|
||||
- vddrfa1p7-supply
|
||||
- vddrfacmn-supply
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
- $ref: qcom,bluetooth-common.yaml
|
||||
- $ref: /schemas/serial/serial-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial {
|
||||
bluetooth {
|
||||
compatible = "qcom,qca6390-bt";
|
||||
vddaon-supply = <&vreg_pmu_aon_0p59>;
|
||||
vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>;
|
||||
vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
|
||||
vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
|
||||
vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
|
||||
vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qcom,qca9377-bt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QCA9377 Bluetooth
|
||||
|
||||
maintainers:
|
||||
- Balakrishna Godavarthi <quic_bgodavar@quicinc.com>
|
||||
- Rocky Liao <quic_rjliao@quicinc.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,qca9377-bt
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: External low-power 32.768 kHz clock input
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
|
||||
vddio-supply:
|
||||
description: VDD_IO supply regulator handle
|
||||
|
||||
vddxo-supply:
|
||||
description: VDD_XO supply regulator handle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- enable-gpios
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
- $ref: qcom,bluetooth-common.yaml
|
||||
- $ref: /schemas/serial/serial-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
serial {
|
||||
bluetooth {
|
||||
compatible = "qcom,qca9377-bt";
|
||||
clocks = <&rk809 1>;
|
||||
enable-gpios = <&gpio3 5 GPIO_ACTIVE_HIGH>;
|
||||
max-speed = <2000000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&bt_enable>;
|
||||
vddio-supply = <&vcc_1v8>;
|
||||
vddxo-supply = <&vcc3v3_sys>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qcom,wcn3950-bt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm WCN3950/WCN3988 Bluetooth
|
||||
|
||||
maintainers:
|
||||
- Balakrishna Godavarthi <quic_bgodavar@quicinc.com>
|
||||
- Rocky Liao <quic_rjliao@quicinc.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,wcn3950-bt
|
||||
- qcom,wcn3988-bt
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
|
||||
swctrl-gpios:
|
||||
maxItems: 1
|
||||
description: gpio specifier is used to find status
|
||||
of clock supply to SoC
|
||||
|
||||
vddch0-supply:
|
||||
description: VDD_CH0 supply regulator handle
|
||||
|
||||
vddio-supply:
|
||||
description: VDD_IO supply regulator handle
|
||||
|
||||
vddrf-supply:
|
||||
description: VDD_RF supply regulator handle
|
||||
|
||||
vddxo-supply:
|
||||
description: VDD_XO supply regulator handle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- vddch0-supply
|
||||
- vddio-supply
|
||||
- vddrf-supply
|
||||
- vddxo-supply
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
- $ref: qcom,bluetooth-common.yaml
|
||||
- $ref: /schemas/serial/serial-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
serial {
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn3950-bt";
|
||||
enable-gpios = <&tlmm 87 GPIO_ACTIVE_HIGH>;
|
||||
max-speed = <3200000>;
|
||||
vddch0-supply = <&pm4125_l22>;
|
||||
vddio-supply = <&pm4125_l15>;
|
||||
vddrf-supply = <&pm4125_l10>;
|
||||
vddxo-supply = <&pm4125_l13>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qcom,wcn3990-bt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm WCN3990/WCN3991/WCN3998 Bluetooth
|
||||
|
||||
maintainers:
|
||||
- Balakrishna Godavarthi <quic_bgodavar@quicinc.com>
|
||||
- Rocky Liao <quic_rjliao@quicinc.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,wcn3990-bt
|
||||
- qcom,wcn3991-bt
|
||||
- qcom,wcn3998-bt
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: External low-power 32.768 kHz clock input
|
||||
|
||||
vddch0-supply:
|
||||
description: VDD_CH0 supply regulator handle
|
||||
|
||||
vddch1-supply:
|
||||
description: VDD_CH1 supply regulator handle
|
||||
|
||||
vddio-supply:
|
||||
description: VDD_IO supply regulator handle
|
||||
|
||||
vddrf-supply:
|
||||
description: VDD_RF supply regulator handle
|
||||
|
||||
vddxo-supply:
|
||||
description: VDD_XO supply regulator handle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- vddch0-supply
|
||||
- vddio-supply
|
||||
- vddrf-supply
|
||||
- vddxo-supply
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
- $ref: qcom,bluetooth-common.yaml
|
||||
- $ref: /schemas/serial/serial-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial {
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn3990-bt";
|
||||
firmware-name = "crnv21.bin";
|
||||
max-speed = <3200000>;
|
||||
vddio-supply = <&vreg_s4a_1p8>;
|
||||
vddch0-supply = <&vreg_l25a_3p3>;
|
||||
vddch1-supply = <&vreg_l23a_3p3>;
|
||||
vddrf-supply = <&vreg_l17a_1p3>;
|
||||
vddxo-supply = <&vreg_l7a_1p8>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qcom,wcn6750-bt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm WCN6750 Bluetooth
|
||||
|
||||
maintainers:
|
||||
- Balakrishna Godavarthi <quic_bgodavar@quicinc.com>
|
||||
- Rocky Liao <quic_rjliao@quicinc.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,wcn6750-bt
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
|
||||
swctrl-gpios:
|
||||
maxItems: 1
|
||||
description: gpio specifier is used to find status
|
||||
of clock supply to SoC
|
||||
deprecated: true
|
||||
|
||||
vddaon-supply:
|
||||
description: VDD_AON supply regulator handle
|
||||
|
||||
vddasd-supply:
|
||||
description: VDD_ASD supply regulator handle
|
||||
deprecated: true
|
||||
|
||||
vddbtcmx-supply:
|
||||
description: VDD_BT_CMX supply regulator handle
|
||||
|
||||
vddbtcxmx-supply:
|
||||
description: VDD_BT_CXMX supply regulator handle
|
||||
deprecated: true
|
||||
|
||||
vddio-supply:
|
||||
description: VDD_IO supply regulator handle
|
||||
deprecated: true
|
||||
|
||||
vddrfa0p8-supply:
|
||||
description: VDD_RFA_0P8 supply regulator handle
|
||||
|
||||
vddrfa1p2-supply:
|
||||
description: VDD_RFA_1P2 supply regulator handle
|
||||
|
||||
vddrfa1p7-supply:
|
||||
description: VDD_RFA_1P7 supply regulator handle
|
||||
|
||||
vddrfa2p2-supply:
|
||||
description: VDD_RFA_2P2 supply regulator handle
|
||||
|
||||
vddrfacmn-supply:
|
||||
description: VDD_RFA_CMN supply regulator handle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- vddaon-supply
|
||||
- vddrfa0p8-supply
|
||||
- vddrfa1p2-supply
|
||||
- vddrfa1p7-supply
|
||||
- vddrfacmn-supply
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
- $ref: qcom,bluetooth-common.yaml
|
||||
- $ref: /schemas/serial/serial-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial {
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn6750-bt";
|
||||
|
||||
firmware-name = "msnv11.bin";
|
||||
max-speed = <3200000>;
|
||||
vddaon-supply = <&vreg_pmu_aon_0p59>;
|
||||
vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>;
|
||||
vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
|
||||
vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
|
||||
vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
|
||||
vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qcom,wcn6855-bt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm WCN6855 Bluetooth
|
||||
|
||||
maintainers:
|
||||
- Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
- Balakrishna Godavarthi <quic_bgodavar@quicinc.com>
|
||||
- Rocky Liao <quic_rjliao@quicinc.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,wcn6855-bt
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
|
||||
swctrl-gpios:
|
||||
maxItems: 1
|
||||
description: gpio specifier is used to find status
|
||||
of clock supply to SoC
|
||||
deprecated: true
|
||||
|
||||
vddaon-supply:
|
||||
description: VDD_AON supply regulator handle
|
||||
|
||||
vddbtcmx-supply:
|
||||
description: VDD_BT_CMX supply regulator handle
|
||||
|
||||
vddbtcxmx-supply:
|
||||
description: VDD_BT_CXMX supply regulator handle
|
||||
deprecated: true
|
||||
|
||||
vddio-supply:
|
||||
description: VDD_IO supply regulator handle
|
||||
deprecated: true
|
||||
|
||||
vddrfa0p8-supply:
|
||||
description: VDD_RFA_0P8 supply regulator handle
|
||||
|
||||
vddrfa1p2-supply:
|
||||
description: VDD_RFA_1P2 supply regulator handle
|
||||
|
||||
vddrfa1p7-supply:
|
||||
description: VDD_RFA_1P7 supply regulator handle
|
||||
deprecated: true
|
||||
|
||||
vddrfa1p8-supply:
|
||||
description: VDD_RFA_1P8 supply regulator handle
|
||||
|
||||
vddrfacmn-supply:
|
||||
description: VDD_RFA_CMN supply regulator handle
|
||||
|
||||
vddwlcx-supply:
|
||||
description: VDD_WLCX supply regulator handle
|
||||
|
||||
vddwlmx-supply:
|
||||
description: VDD_WLMX supply regulator handle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- vddaon-supply
|
||||
- vddbtcmx-supply
|
||||
- vddrfa0p8-supply
|
||||
- vddrfa1p2-supply
|
||||
- vddrfa1p8-supply
|
||||
- vddrfacmn-supply
|
||||
- vddwlcx-supply
|
||||
- vddwlmx-supply
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
- $ref: qcom,bluetooth-common.yaml
|
||||
- $ref: /schemas/serial/serial-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial {
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn6855-bt";
|
||||
|
||||
max-speed = <3000000>;
|
||||
vddaon-supply = <&vreg_pmu_aon_0p8>;
|
||||
vddbtcmx-supply = <&vreg_pmu_btcmx_0p8>;
|
||||
vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
|
||||
vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
|
||||
vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>;
|
||||
vddrfacmn-supply = <&vreg_pmu_rfa_cmn_0p8>;
|
||||
vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
|
||||
vddwlmx-supply = <&vreg_pmu_wlmx_0p8>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qcom,wcn7850-bt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm WCN7850 Bluetooth
|
||||
|
||||
maintainers:
|
||||
- Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
- Balakrishna Godavarthi <quic_bgodavar@quicinc.com>
|
||||
- Rocky Liao <quic_rjliao@quicinc.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,wcn7850-bt
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
|
||||
swctrl-gpios:
|
||||
maxItems: 1
|
||||
description: gpio specifier is used to find status
|
||||
of clock supply to SoC
|
||||
deprecated: true
|
||||
|
||||
vddaon-supply:
|
||||
description: VDD_AON supply regulator handle
|
||||
|
||||
vdddig-supply:
|
||||
description: VDD_DIG supply regulator handle
|
||||
deprecated: true
|
||||
|
||||
vddio-supply:
|
||||
description: VDD_IO supply regulator handle
|
||||
deprecated: true
|
||||
|
||||
vddrfa0p8-supply:
|
||||
description: VDD_RFA_0P8 supply regulator handle
|
||||
|
||||
vddrfa1p2-supply:
|
||||
description: VDD_RFA_1P2 supply regulator handle
|
||||
|
||||
vddrfa1p8-supply:
|
||||
description: VDD_RFA_1P8 supply regulator handle
|
||||
|
||||
vddrfa1p9-supply:
|
||||
description: VDD_RFA_1P9 supply regulator handle
|
||||
deprecated: true
|
||||
|
||||
vddrfacmn-supply:
|
||||
description: VDD_RFA_CMN supply regulator handle
|
||||
|
||||
vddwlcx-supply:
|
||||
description: VDD_WLCX supply regulator handle
|
||||
|
||||
vddwlmx-supply:
|
||||
description: VDD_WLMX supply regulator handle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- vddrfacmn-supply
|
||||
- vddaon-supply
|
||||
- vddwlcx-supply
|
||||
- vddwlmx-supply
|
||||
- vddrfa0p8-supply
|
||||
- vddrfa1p2-supply
|
||||
- vddrfa1p8-supply
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
- $ref: qcom,bluetooth-common.yaml
|
||||
- $ref: /schemas/serial/serial-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial {
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn7850-bt";
|
||||
|
||||
max-speed = <3200000>;
|
||||
vddaon-supply = <&vreg_pmu_aon_0p59>;
|
||||
vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
|
||||
vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
|
||||
vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>;
|
||||
vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
|
||||
vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
|
||||
vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
|
||||
};
|
||||
};
|
||||
|
|
@ -1,259 +0,0 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/qualcomm-bluetooth.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Bluetooth Chips
|
||||
|
||||
maintainers:
|
||||
- Balakrishna Godavarthi <quic_bgodavar@quicinc.com>
|
||||
- Rocky Liao <quic_rjliao@quicinc.com>
|
||||
|
||||
description:
|
||||
This binding describes Qualcomm UART-attached bluetooth chips.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,qca2066-bt
|
||||
- qcom,qca6174-bt
|
||||
- qcom,qca9377-bt
|
||||
- qcom,wcn3950-bt
|
||||
- qcom,wcn3988-bt
|
||||
- qcom,wcn3990-bt
|
||||
- qcom,wcn3991-bt
|
||||
- qcom,wcn3998-bt
|
||||
- qcom,qca6390-bt
|
||||
- qcom,wcn6750-bt
|
||||
- qcom,wcn6855-bt
|
||||
- qcom,wcn7850-bt
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
description: gpio specifier used to enable chip
|
||||
|
||||
swctrl-gpios:
|
||||
maxItems: 1
|
||||
description: gpio specifier is used to find status
|
||||
of clock supply to SoC
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description: clock provided to the controller (SUSCLK_32KHZ)
|
||||
|
||||
vddio-supply:
|
||||
description: VDD_IO supply regulator handle
|
||||
|
||||
vddxo-supply:
|
||||
description: VDD_XO supply regulator handle
|
||||
|
||||
vddrf-supply:
|
||||
description: VDD_RF supply regulator handle
|
||||
|
||||
vddch0-supply:
|
||||
description: VDD_CH0 supply regulator handle
|
||||
|
||||
vddch1-supply:
|
||||
description: VDD_CH1 supply regulator handle
|
||||
|
||||
vddaon-supply:
|
||||
description: VDD_AON supply regulator handle
|
||||
|
||||
vdddig-supply:
|
||||
description: VDD_DIG supply regulator handle
|
||||
|
||||
vddbtcmx-supply:
|
||||
description: VDD_BT_CMX supply regulator handle
|
||||
|
||||
vddbtcxmx-supply:
|
||||
description: VDD_BT_CXMX supply regulator handle
|
||||
|
||||
vddrfacmn-supply:
|
||||
description: VDD_RFA_CMN supply regulator handle
|
||||
|
||||
vddrfa0p8-supply:
|
||||
description: VDD_RFA_0P8 supply regulator handle
|
||||
|
||||
vddrfa1p7-supply:
|
||||
description: VDD_RFA_1P7 supply regulator handle
|
||||
|
||||
vddrfa1p8-supply:
|
||||
description: VDD_RFA_1P8 supply regulator handle
|
||||
|
||||
vddrfa1p2-supply:
|
||||
description: VDD_RFA_1P2 supply regulator handle
|
||||
|
||||
vddrfa1p9-supply:
|
||||
description: VDD_RFA_1P9 supply regulator handle
|
||||
|
||||
vddrfa2p2-supply:
|
||||
description: VDD_RFA_2P2 supply regulator handle
|
||||
|
||||
vddasd-supply:
|
||||
description: VDD_ASD supply regulator handle
|
||||
|
||||
vddwlcx-supply:
|
||||
description: VDD_WLCX supply regulator handle
|
||||
|
||||
vddwlmx-supply:
|
||||
description: VDD_WLMX supply regulator handle
|
||||
|
||||
max-speed: true
|
||||
|
||||
firmware-name:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: specify the name of nvm firmware to load
|
||||
- description: specify the name of rampatch firmware to load
|
||||
|
||||
local-bd-address: true
|
||||
|
||||
qcom,local-bd-address-broken:
|
||||
type: boolean
|
||||
description:
|
||||
boot firmware is incorrectly passing the address in big-endian order
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
- $ref: /schemas/serial/serial-peripheral-props.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qca2066-bt
|
||||
- qcom,qca6174-bt
|
||||
then:
|
||||
required:
|
||||
- enable-gpios
|
||||
- clocks
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,wcn3950-bt
|
||||
- qcom,wcn3988-bt
|
||||
- qcom,wcn3990-bt
|
||||
- qcom,wcn3991-bt
|
||||
- qcom,wcn3998-bt
|
||||
then:
|
||||
required:
|
||||
- vddio-supply
|
||||
- vddxo-supply
|
||||
- vddrf-supply
|
||||
- vddch0-supply
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,wcn6750-bt
|
||||
then:
|
||||
required:
|
||||
- vddaon-supply
|
||||
- vddrfacmn-supply
|
||||
- vddrfa0p8-supply
|
||||
- vddrfa1p7-supply
|
||||
- vddrfa1p2-supply
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,wcn6855-bt
|
||||
then:
|
||||
required:
|
||||
- vddrfacmn-supply
|
||||
- vddaon-supply
|
||||
- vddwlcx-supply
|
||||
- vddwlmx-supply
|
||||
- vddbtcmx-supply
|
||||
- vddrfa0p8-supply
|
||||
- vddrfa1p2-supply
|
||||
- vddrfa1p8-supply
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,wcn7850-bt
|
||||
then:
|
||||
required:
|
||||
- vddrfacmn-supply
|
||||
- vddaon-supply
|
||||
- vddwlcx-supply
|
||||
- vddwlmx-supply
|
||||
- vddrfa0p8-supply
|
||||
- vddrfa1p2-supply
|
||||
- vddrfa1p8-supply
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qca6390-bt
|
||||
then:
|
||||
required:
|
||||
- vddrfacmn-supply
|
||||
- vddaon-supply
|
||||
- vddbtcmx-supply
|
||||
- vddrfa0p8-supply
|
||||
- vddrfa1p2-supply
|
||||
- vddrfa1p7-supply
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
serial {
|
||||
|
||||
bluetooth {
|
||||
compatible = "qcom,qca6174-bt";
|
||||
enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>;
|
||||
clocks = <&divclk4>;
|
||||
firmware-name = "nvm_00440302.bin";
|
||||
};
|
||||
};
|
||||
- |
|
||||
serial {
|
||||
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn3990-bt";
|
||||
vddio-supply = <&vreg_s4a_1p8>;
|
||||
vddxo-supply = <&vreg_l7a_1p8>;
|
||||
vddrf-supply = <&vreg_l17a_1p3>;
|
||||
vddch0-supply = <&vreg_l25a_3p3>;
|
||||
max-speed = <3200000>;
|
||||
firmware-name = "crnv21.bin";
|
||||
};
|
||||
};
|
||||
- |
|
||||
serial {
|
||||
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn6750-bt";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&bt_en_default>;
|
||||
enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>;
|
||||
swctrl-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
|
||||
vddio-supply = <&vreg_l19b_1p8>;
|
||||
vddaon-supply = <&vreg_s7b_0p9>;
|
||||
vddbtcxmx-supply = <&vreg_s7b_0p9>;
|
||||
vddrfacmn-supply = <&vreg_s7b_0p9>;
|
||||
vddrfa0p8-supply = <&vreg_s7b_0p9>;
|
||||
vddrfa1p7-supply = <&vreg_s1b_1p8>;
|
||||
vddrfa1p2-supply = <&vreg_s8b_1p2>;
|
||||
vddrfa2p2-supply = <&vreg_s1c_2p2>;
|
||||
vddasd-supply = <&vreg_l11c_2p8>;
|
||||
max-speed = <3200000>;
|
||||
firmware-name = "msnv11.bin";
|
||||
};
|
||||
};
|
||||
|
|
@ -21379,6 +21379,7 @@ QUALCOMM BLUETOOTH DRIVER
|
|||
M: Bartosz Golaszewski <brgl@kernel.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/bluetooth/qcom,*
|
||||
F: drivers/bluetooth/btqca.[ch]
|
||||
F: drivers/bluetooth/btqcomsmd.c
|
||||
F: drivers/bluetooth/hci_qca.c
|
||||
|
|
|
|||
|
|
@ -1190,8 +1190,7 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
|
|||
skb = NULL; /* skb is freed in the callee */
|
||||
|
||||
exit_error:
|
||||
if (skb)
|
||||
kfree_skb(skb);
|
||||
kfree_skb(skb);
|
||||
|
||||
if (ret)
|
||||
hdev->stat.err_rx++;
|
||||
|
|
|
|||
|
|
@ -1472,7 +1472,6 @@ static void btmtksdio_remove(struct sdio_func *func)
|
|||
hci_free_dev(hdev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int btmtksdio_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct sdio_func *func = dev_to_sdio_func(dev);
|
||||
|
|
@ -1542,18 +1541,13 @@ static const struct dev_pm_ops btmtksdio_pm_ops = {
|
|||
RUNTIME_PM_OPS(btmtksdio_runtime_suspend, btmtksdio_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
#define BTMTKSDIO_PM_OPS (&btmtksdio_pm_ops)
|
||||
#else /* CONFIG_PM */
|
||||
#define BTMTKSDIO_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct sdio_driver btmtksdio_driver = {
|
||||
.name = "btmtksdio",
|
||||
.probe = btmtksdio_probe,
|
||||
.remove = btmtksdio_remove,
|
||||
.id_table = btmtksdio_table,
|
||||
.drv = {
|
||||
.pm = BTMTKSDIO_PM_OPS,
|
||||
.pm = pm_ptr(&btmtksdio_pm_ops),
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1947,8 +1947,7 @@ static void nxp_serdev_remove(struct serdev_device *serdev)
|
|||
hci_free_dev(hdev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int nxp_serdev_suspend(struct device *dev)
|
||||
static int __maybe_unused nxp_serdev_suspend(struct device *dev)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = dev_get_drvdata(dev);
|
||||
struct ps_data *psdata = &nxpdev->psdata;
|
||||
|
|
@ -1962,7 +1961,7 @@ static int nxp_serdev_suspend(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int nxp_serdev_resume(struct device *dev)
|
||||
static int __maybe_unused nxp_serdev_resume(struct device *dev)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = dev_get_drvdata(dev);
|
||||
struct ps_data *psdata = &nxpdev->psdata;
|
||||
|
|
@ -1975,7 +1974,6 @@ static int nxp_serdev_resume(struct device *dev)
|
|||
ps_control(psdata->hdev, PS_STATE_AWAKE);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
static void nxp_serdev_coredump(struct device *dev)
|
||||
|
|
|
|||
|
|
@ -581,28 +581,11 @@ static int qca_download_firmware(struct hci_dev *hdev,
|
|||
|
||||
ret = request_firmware(&fw, config->fwname, &hdev->dev);
|
||||
if (ret) {
|
||||
/* For WCN6750, if mbn file is not present then check for
|
||||
* tlv file.
|
||||
*/
|
||||
if (soc_type == QCA_WCN6750 && config->type == ELF_TYPE_PATCH) {
|
||||
bt_dev_dbg(hdev, "QCA Failed to request file: %s (%d)",
|
||||
config->fwname, ret);
|
||||
config->type = TLV_TYPE_PATCH;
|
||||
snprintf(config->fwname, sizeof(config->fwname),
|
||||
"qca/msbtfw%02x.tlv", rom_ver);
|
||||
bt_dev_info(hdev, "QCA Downloading %s", config->fwname);
|
||||
ret = request_firmware(&fw, config->fwname, &hdev->dev);
|
||||
if (ret) {
|
||||
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
|
||||
config->fwname, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
/* If the board-specific file is missing, try loading the default
|
||||
* one, unless that was attempted already.
|
||||
*/
|
||||
else if (config->type == TLV_TYPE_NVM &&
|
||||
qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) {
|
||||
if (config->type == TLV_TYPE_NVM &&
|
||||
qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) {
|
||||
bt_dev_info(hdev, "QCA Downloading %s", config->fwname);
|
||||
ret = request_firmware(&fw, config->fwname, &hdev->dev);
|
||||
if (ret) {
|
||||
|
|
@ -847,8 +830,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
"qca/msbtfw%02x.mbn", rom_ver);
|
||||
break;
|
||||
case QCA_WCN6855:
|
||||
/* Due to historical reasons, WCN685x chip has been using firmware
|
||||
* without the "wcn" prefix. The mapping between the chip and its
|
||||
* corresponding firmware has now been corrected.
|
||||
*/
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/hpbtfw%02x.tlv", rom_ver);
|
||||
"qca/wcnhpbtfw%02x.tlv", rom_ver);
|
||||
break;
|
||||
case QCA_WCN7850:
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
|
|
@ -861,8 +848,26 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
}
|
||||
|
||||
err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
|
||||
/* For WCN6750, if mbn file is not present then check for
|
||||
* tlv file.
|
||||
*/
|
||||
if (err < 0 && soc_type == QCA_WCN6750) {
|
||||
bt_dev_dbg(hdev, "QCA Failed to request file: %s (%d)",
|
||||
config.fwname, err);
|
||||
config.type = TLV_TYPE_PATCH;
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/msbtfw%02x.tlv", rom_ver);
|
||||
bt_dev_info(hdev, "QCA Downloading %s", config.fwname);
|
||||
err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
|
||||
} else if (err < 0 && !rampatch_name && soc_type == QCA_WCN6855) {
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/hpbtfw%02x.tlv", rom_ver);
|
||||
err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "QCA Failed to download patch (%d)", err);
|
||||
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
|
||||
config.fwname, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -923,7 +928,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
case QCA_WCN6855:
|
||||
qca_read_fw_board_id(hdev, &boardid);
|
||||
qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
|
||||
"hpnv", soc_type, ver, rom_ver, boardid);
|
||||
"wcnhpnv", soc_type, ver, rom_ver, boardid);
|
||||
break;
|
||||
case QCA_WCN7850:
|
||||
qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
|
||||
|
|
@ -936,8 +941,15 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
}
|
||||
|
||||
err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
|
||||
if (err < 0 && !firmware_name && soc_type == QCA_WCN6855) {
|
||||
qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
|
||||
"hpnv", soc_type, ver, rom_ver, boardid);
|
||||
err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err);
|
||||
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
|
||||
config.fwname, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -521,12 +521,16 @@ static const struct usb_device_id quirks_table[] = {
|
|||
{ USB_DEVICE(0x0bda, 0xb850), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x13d3, 0x3600), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x13d3, 0x3601), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x0489, 0xe112), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek 8851BU Bluetooth devices */
|
||||
{ USB_DEVICE(0x3625, 0x010b), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x2001, 0x332a), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x7392, 0xe611), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek 8852AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK |
|
||||
|
|
@ -557,6 +561,8 @@ static const struct usb_device_id quirks_table[] = {
|
|||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3592), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3612), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe122), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
|
|
@ -577,8 +583,6 @@ static const struct usb_device_id quirks_table[] = {
|
|||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3591), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3618), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe123), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe125), .driver_info = BTUSB_REALTEK |
|
||||
|
|
@ -637,6 +641,8 @@ static const struct usb_device_id quirks_table[] = {
|
|||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3622), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe158), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Additional MediaTek MT7921 Bluetooth devices */
|
||||
{ USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK |
|
||||
|
|
@ -773,6 +779,7 @@ static const struct usb_device_id quirks_table[] = {
|
|||
|
||||
/* Additional Realtek 8723BU Bluetooth devices */
|
||||
{ USB_DEVICE(0x7392, 0xa611), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x2c0a, 0x8761), .driver_info = BTUSB_REALTEK },
|
||||
|
||||
/* Additional Realtek 8723DE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0bda, 0xb009), .driver_info = BTUSB_REALTEK },
|
||||
|
|
@ -4462,17 +4469,17 @@ static void btusb_disconnect(struct usb_interface *intf)
|
|||
kfree(data);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
{
|
||||
struct btusb_data *data = usb_get_intfdata(intf);
|
||||
|
||||
BT_DBG("intf %p", intf);
|
||||
|
||||
/* Don't auto-suspend if there are connections; external suspend calls
|
||||
* shall never fail.
|
||||
/* Don't auto-suspend if there are connections or discovery in
|
||||
* progress; external suspend calls shall never fail.
|
||||
*/
|
||||
if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev))
|
||||
if (PMSG_IS_AUTO(message) &&
|
||||
(hci_conn_count(data->hdev) || hci_discovery_active(data->hdev)))
|
||||
return -EBUSY;
|
||||
|
||||
if (data->suspend_count++)
|
||||
|
|
@ -4616,7 +4623,6 @@ static int btusb_resume(struct usb_interface *intf)
|
|||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
static void btusb_coredump(struct device *dev)
|
||||
|
|
@ -4633,10 +4639,8 @@ static struct usb_driver btusb_driver = {
|
|||
.name = "btusb",
|
||||
.probe = btusb_probe,
|
||||
.disconnect = btusb_disconnect,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = btusb_suspend,
|
||||
.resume = btusb_resume,
|
||||
#endif
|
||||
.suspend = pm_ptr(btusb_suspend),
|
||||
.resume = pm_ptr(btusb_resume),
|
||||
.id_table = btusb_table,
|
||||
.supports_autosuspend = 1,
|
||||
.disable_hub_initiated_lpm = 1,
|
||||
|
|
|
|||
|
|
@ -2416,8 +2416,9 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
hdev);
|
||||
}
|
||||
|
||||
static int bcm4377_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
static int bcm4377_suspend(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct bcm4377_data *bcm4377 = pci_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
|
|
@ -2431,8 +2432,9 @@ static int bcm4377_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bcm4377_resume(struct pci_dev *pdev)
|
||||
static int bcm4377_resume(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct bcm4377_data *bcm4377 = pci_get_drvdata(pdev);
|
||||
|
||||
iowrite32(BCM4377_BAR0_SLEEP_CONTROL_UNQUIESCE,
|
||||
|
|
@ -2441,6 +2443,8 @@ static int bcm4377_resume(struct pci_dev *pdev)
|
|||
return hci_resume_dev(bcm4377->hdev);
|
||||
}
|
||||
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(bcm4377_ops, bcm4377_suspend, bcm4377_resume);
|
||||
|
||||
static const struct dmi_system_id bcm4377_dmi_board_table[] = {
|
||||
{
|
||||
.matches = {
|
||||
|
|
@ -2541,8 +2545,7 @@ static struct pci_driver bcm4377_pci_driver = {
|
|||
.name = "hci_bcm4377",
|
||||
.id_table = bcm4377_devid_table,
|
||||
.probe = bcm4377_probe,
|
||||
.suspend = bcm4377_suspend,
|
||||
.resume = bcm4377_resume,
|
||||
.driver.pm = &bcm4377_ops,
|
||||
};
|
||||
module_pci_driver(bcm4377_pci_driver);
|
||||
|
||||
|
|
|
|||
|
|
@ -126,7 +126,6 @@ static int intel_wait_booting(struct hci_uart *hu)
|
|||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int intel_wait_lpm_transaction(struct hci_uart *hu)
|
||||
{
|
||||
struct intel_data *intel = hu->priv;
|
||||
|
|
@ -237,7 +236,6 @@ static int intel_lpm_resume(struct hci_uart *hu)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static int intel_lpm_host_wake(struct hci_uart *hu)
|
||||
{
|
||||
|
|
@ -1066,7 +1064,6 @@ static const struct acpi_device_id intel_acpi_match[] = {
|
|||
MODULE_DEVICE_TABLE(acpi, intel_acpi_match);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int intel_suspend_device(struct device *dev)
|
||||
{
|
||||
struct intel_device *idev = dev_get_drvdata(dev);
|
||||
|
|
@ -1090,10 +1087,8 @@ static int intel_resume_device(struct device *dev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int intel_suspend(struct device *dev)
|
||||
static int __maybe_unused intel_suspend(struct device *dev)
|
||||
{
|
||||
struct intel_device *idev = dev_get_drvdata(dev);
|
||||
|
||||
|
|
@ -1103,7 +1098,7 @@ static int intel_suspend(struct device *dev)
|
|||
return intel_suspend_device(dev);
|
||||
}
|
||||
|
||||
static int intel_resume(struct device *dev)
|
||||
static int __maybe_unused intel_resume(struct device *dev)
|
||||
{
|
||||
struct intel_device *idev = dev_get_drvdata(dev);
|
||||
|
||||
|
|
@ -1112,7 +1107,6 @@ static int intel_resume(struct device *dev)
|
|||
|
||||
return intel_resume_device(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops intel_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume)
|
||||
|
|
|
|||
|
|
@ -685,6 +685,8 @@ static int hci_uart_register_dev(struct hci_uart *hu)
|
|||
return err;
|
||||
}
|
||||
|
||||
set_bit(HCI_UART_PROTO_INIT, &hu->flags);
|
||||
|
||||
if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
|
||||
return 0;
|
||||
|
||||
|
|
@ -712,8 +714,6 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
|
|||
|
||||
hu->proto = p;
|
||||
|
||||
set_bit(HCI_UART_PROTO_INIT, &hu->flags);
|
||||
|
||||
err = hci_uart_register_dev(hu);
|
||||
if (err) {
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ enum qca_flags {
|
|||
enum qca_capabilities {
|
||||
QCA_CAP_WIDEBAND_SPEECH = BIT(0),
|
||||
QCA_CAP_VALID_LE_STATES = BIT(1),
|
||||
QCA_CAP_HFP_HW_OFFLOAD = BIT(2),
|
||||
};
|
||||
|
||||
/* HCI_IBS transmit side sleep protocol states */
|
||||
|
|
@ -229,6 +230,7 @@ struct qca_serdev {
|
|||
u32 init_speed;
|
||||
u32 oper_speed;
|
||||
bool bdaddr_property_broken;
|
||||
bool support_hfp_hw_offload;
|
||||
const char *firmware_name[2];
|
||||
};
|
||||
|
||||
|
|
@ -1653,6 +1655,39 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
|
|||
skb_queue_purge(&qca->rx_memdump_q);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the BT chip's bt_en pin is connected to a 3.3V power supply via
|
||||
* hardware and always stays high, driver cannot control the bt_en pin.
|
||||
* As a result, during SSR (SubSystem Restart), QCA_SSR_TRIGGERED and
|
||||
* QCA_IBS_DISABLED flags cannot be cleared, which leads to a reset
|
||||
* command timeout.
|
||||
* Add an msleep delay to ensure controller completes the SSR process.
|
||||
*
|
||||
* Host will not download the firmware after SSR, controller to remain
|
||||
* in the IBS_WAKE state, and the host needs to synchronize with it
|
||||
*
|
||||
* Since the bluetooth chip has been reset, clear the memdump state.
|
||||
*/
|
||||
if (!hci_test_quirk(hu->hdev, HCI_QUIRK_NON_PERSISTENT_SETUP)) {
|
||||
/*
|
||||
* When the SSR (SubSystem Restart) duration exceeds 2 seconds,
|
||||
* it triggers host tx_idle_delay, which sets host TX state
|
||||
* to sleep. Reset tx_idle_timer after SSR to prevent
|
||||
* host enter TX IBS_Sleep mode.
|
||||
*/
|
||||
mod_timer(&qca->tx_idle_timer, jiffies +
|
||||
msecs_to_jiffies(qca->tx_idle_delay));
|
||||
|
||||
/* Controller reset completion time is 50ms */
|
||||
msleep(50);
|
||||
|
||||
clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
|
||||
clear_bit(QCA_IBS_DISABLED, &qca->flags);
|
||||
|
||||
qca->tx_ibs_state = HCI_IBS_TX_AWAKE;
|
||||
qca->memdump_state = QCA_MEMDUMP_IDLE;
|
||||
}
|
||||
|
||||
clear_bit(QCA_HW_ERROR_EVENT, &qca->flags);
|
||||
}
|
||||
|
||||
|
|
@ -1879,7 +1914,7 @@ static int qca_setup(struct hci_uart *hu)
|
|||
const char *rampatch_name = qca_get_rampatch_name(hu);
|
||||
int ret;
|
||||
struct qca_btsoc_version ver;
|
||||
struct qca_serdev *qcadev;
|
||||
struct qca_serdev *qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
const char *soc_name;
|
||||
|
||||
ret = qca_check_speeds(hu);
|
||||
|
|
@ -1943,7 +1978,6 @@ static int qca_setup(struct hci_uart *hu)
|
|||
case QCA_WCN6750:
|
||||
case QCA_WCN6855:
|
||||
case QCA_WCN7850:
|
||||
qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
if (qcadev->bdaddr_property_broken)
|
||||
hci_set_quirk(hdev, HCI_QUIRK_BDADDR_PROPERTY_BROKEN);
|
||||
|
||||
|
|
@ -2033,7 +2067,7 @@ static int qca_setup(struct hci_uart *hu)
|
|||
else
|
||||
hu->hdev->set_bdaddr = qca_set_bdaddr;
|
||||
|
||||
if (soc_type == QCA_QCA2066)
|
||||
if (qcadev->support_hfp_hw_offload)
|
||||
qca_configure_hfp_offload(hdev);
|
||||
|
||||
qca->fw_version = le16_to_cpu(ver.patch_ver);
|
||||
|
|
@ -2117,7 +2151,8 @@ static const struct qca_device_data qca_soc_data_wcn3998 __maybe_unused = {
|
|||
static const struct qca_device_data qca_soc_data_qca2066 __maybe_unused = {
|
||||
.soc_type = QCA_QCA2066,
|
||||
.num_vregs = 0,
|
||||
.capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES,
|
||||
.capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES |
|
||||
QCA_CAP_HFP_HW_OFFLOAD,
|
||||
};
|
||||
|
||||
static const struct qca_device_data qca_soc_data_qca6390 __maybe_unused = {
|
||||
|
|
@ -2153,7 +2188,8 @@ static const struct qca_device_data qca_soc_data_wcn6855 __maybe_unused = {
|
|||
{ "vddrfa1p2", 257000 },
|
||||
},
|
||||
.num_vregs = 6,
|
||||
.capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES,
|
||||
.capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES |
|
||||
QCA_CAP_HFP_HW_OFFLOAD,
|
||||
};
|
||||
|
||||
static const struct qca_device_data qca_soc_data_wcn7850 __maybe_unused = {
|
||||
|
|
@ -2167,7 +2203,8 @@ static const struct qca_device_data qca_soc_data_wcn7850 __maybe_unused = {
|
|||
{ "vddrfa1p9", 302000 },
|
||||
},
|
||||
.num_vregs = 6,
|
||||
.capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES,
|
||||
.capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES |
|
||||
QCA_CAP_HFP_HW_OFFLOAD,
|
||||
};
|
||||
|
||||
static void qca_power_shutdown(struct hci_uart *hu)
|
||||
|
|
@ -2502,6 +2539,9 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
|||
|
||||
if (!(data->capabilities & QCA_CAP_VALID_LE_STATES))
|
||||
hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LE_STATES);
|
||||
|
||||
if (data->capabilities & QCA_CAP_HFP_HW_OFFLOAD)
|
||||
qcadev->support_hfp_hw_offload = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -130,21 +130,30 @@ struct bt_voice {
|
|||
#define BT_RCVMTU 13
|
||||
#define BT_PHY 14
|
||||
|
||||
#define BT_PHY_BR_1M_1SLOT 0x00000001
|
||||
#define BT_PHY_BR_1M_3SLOT 0x00000002
|
||||
#define BT_PHY_BR_1M_5SLOT 0x00000004
|
||||
#define BT_PHY_EDR_2M_1SLOT 0x00000008
|
||||
#define BT_PHY_EDR_2M_3SLOT 0x00000010
|
||||
#define BT_PHY_EDR_2M_5SLOT 0x00000020
|
||||
#define BT_PHY_EDR_3M_1SLOT 0x00000040
|
||||
#define BT_PHY_EDR_3M_3SLOT 0x00000080
|
||||
#define BT_PHY_EDR_3M_5SLOT 0x00000100
|
||||
#define BT_PHY_LE_1M_TX 0x00000200
|
||||
#define BT_PHY_LE_1M_RX 0x00000400
|
||||
#define BT_PHY_LE_2M_TX 0x00000800
|
||||
#define BT_PHY_LE_2M_RX 0x00001000
|
||||
#define BT_PHY_LE_CODED_TX 0x00002000
|
||||
#define BT_PHY_LE_CODED_RX 0x00004000
|
||||
#define BT_PHY_BR_1M_1SLOT BIT(0)
|
||||
#define BT_PHY_BR_1M_3SLOT BIT(1)
|
||||
#define BT_PHY_BR_1M_5SLOT BIT(2)
|
||||
#define BT_PHY_EDR_2M_1SLOT BIT(3)
|
||||
#define BT_PHY_EDR_2M_3SLOT BIT(4)
|
||||
#define BT_PHY_EDR_2M_5SLOT BIT(5)
|
||||
#define BT_PHY_EDR_3M_1SLOT BIT(6)
|
||||
#define BT_PHY_EDR_3M_3SLOT BIT(7)
|
||||
#define BT_PHY_EDR_3M_5SLOT BIT(8)
|
||||
#define BT_PHY_LE_1M_TX BIT(9)
|
||||
#define BT_PHY_LE_1M_RX BIT(10)
|
||||
#define BT_PHY_LE_2M_TX BIT(11)
|
||||
#define BT_PHY_LE_2M_RX BIT(12)
|
||||
#define BT_PHY_LE_CODED_TX BIT(13)
|
||||
#define BT_PHY_LE_CODED_RX BIT(14)
|
||||
|
||||
#define BT_PHY_BREDR_MASK (BT_PHY_BR_1M_1SLOT | BT_PHY_BR_1M_3SLOT | \
|
||||
BT_PHY_BR_1M_5SLOT | BT_PHY_EDR_2M_1SLOT | \
|
||||
BT_PHY_EDR_2M_3SLOT | BT_PHY_EDR_2M_5SLOT | \
|
||||
BT_PHY_EDR_3M_1SLOT | BT_PHY_EDR_3M_3SLOT | \
|
||||
BT_PHY_EDR_3M_5SLOT)
|
||||
#define BT_PHY_LE_MASK (BT_PHY_LE_1M_TX | BT_PHY_LE_1M_RX | \
|
||||
BT_PHY_LE_2M_TX | BT_PHY_LE_2M_RX | \
|
||||
BT_PHY_LE_CODED_TX | BT_PHY_LE_CODED_RX)
|
||||
|
||||
#define BT_MODE 15
|
||||
|
||||
|
|
@ -173,7 +182,7 @@ struct bt_iso_io_qos {
|
|||
__u32 interval;
|
||||
__u16 latency;
|
||||
__u16 sdu;
|
||||
__u8 phy;
|
||||
__u8 phys;
|
||||
__u8 rtn;
|
||||
};
|
||||
|
||||
|
|
@ -212,9 +221,9 @@ struct bt_iso_qos {
|
|||
};
|
||||
};
|
||||
|
||||
#define BT_ISO_PHY_1M 0x01
|
||||
#define BT_ISO_PHY_2M 0x02
|
||||
#define BT_ISO_PHY_CODED 0x04
|
||||
#define BT_ISO_PHY_1M BIT(0)
|
||||
#define BT_ISO_PHY_2M BIT(1)
|
||||
#define BT_ISO_PHY_CODED BIT(2)
|
||||
#define BT_ISO_PHY_ANY (BT_ISO_PHY_1M | BT_ISO_PHY_2M | \
|
||||
BT_ISO_PHY_CODED)
|
||||
|
||||
|
|
|
|||
|
|
@ -654,6 +654,8 @@ enum {
|
|||
#define HCI_LE_ISO_BROADCASTER 0x40
|
||||
#define HCI_LE_ISO_SYNC_RECEIVER 0x80
|
||||
#define HCI_LE_LL_EXT_FEATURE 0x80
|
||||
#define HCI_LE_CS 0x40
|
||||
#define HCI_LE_CS_HOST 0x80
|
||||
|
||||
/* Connection modes */
|
||||
#define HCI_CM_ACTIVE 0x0000
|
||||
|
|
@ -1883,6 +1885,15 @@ struct hci_cp_le_set_default_phy {
|
|||
#define HCI_LE_SET_PHY_2M 0x02
|
||||
#define HCI_LE_SET_PHY_CODED 0x04
|
||||
|
||||
#define HCI_OP_LE_SET_PHY 0x2032
|
||||
struct hci_cp_le_set_phy {
|
||||
__le16 handle;
|
||||
__u8 all_phys;
|
||||
__u8 tx_phys;
|
||||
__u8 rx_phys;
|
||||
__le16 phy_opts;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_SET_EXT_SCAN_PARAMS 0x2041
|
||||
struct hci_cp_le_set_ext_scan_params {
|
||||
__u8 own_addr_type;
|
||||
|
|
@ -2136,8 +2147,8 @@ struct hci_cis_params {
|
|||
__u8 cis_id;
|
||||
__le16 c_sdu;
|
||||
__le16 p_sdu;
|
||||
__u8 c_phy;
|
||||
__u8 p_phy;
|
||||
__u8 c_phys;
|
||||
__u8 p_phys;
|
||||
__u8 c_rtn;
|
||||
__u8 p_rtn;
|
||||
} __packed;
|
||||
|
|
@ -2269,6 +2280,204 @@ struct hci_cp_le_read_all_remote_features {
|
|||
__u8 pages;
|
||||
} __packed;
|
||||
|
||||
/* Channel Sounding Commands */
|
||||
#define HCI_OP_LE_CS_RD_LOCAL_SUPP_CAP 0x2089
|
||||
struct hci_rp_le_cs_rd_local_supp_cap {
|
||||
__u8 status;
|
||||
__u8 num_config_supported;
|
||||
__le16 max_consecutive_procedures_supported;
|
||||
__u8 num_antennas_supported;
|
||||
__u8 max_antenna_paths_supported;
|
||||
__u8 roles_supported;
|
||||
__u8 modes_supported;
|
||||
__u8 rtt_capability;
|
||||
__u8 rtt_aa_only_n;
|
||||
__u8 rtt_sounding_n;
|
||||
__u8 rtt_random_payload_n;
|
||||
__le16 nadm_sounding_capability;
|
||||
__le16 nadm_random_capability;
|
||||
__u8 cs_sync_phys_supported;
|
||||
__le16 subfeatures_supported;
|
||||
__le16 t_ip1_times_supported;
|
||||
__le16 t_ip2_times_supported;
|
||||
__le16 t_fcs_times_supported;
|
||||
__le16 t_pm_times_supported;
|
||||
__u8 t_sw_time_supported;
|
||||
__u8 tx_snr_capability;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_RD_RMT_SUPP_CAP 0x208A
|
||||
struct hci_cp_le_cs_rd_local_supp_cap {
|
||||
__le16 handle;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_WR_CACHED_RMT_SUPP_CAP 0x208B
|
||||
struct hci_cp_le_cs_wr_cached_rmt_supp_cap {
|
||||
__le16 handle;
|
||||
__u8 num_config_supported;
|
||||
__le16 max_consecutive_procedures_supported;
|
||||
__u8 num_antennas_supported;
|
||||
__u8 max_antenna_paths_supported;
|
||||
__u8 roles_supported;
|
||||
__u8 modes_supported;
|
||||
__u8 rtt_capability;
|
||||
__u8 rtt_aa_only_n;
|
||||
__u8 rtt_sounding_n;
|
||||
__u8 rtt_random_payload_n;
|
||||
__le16 nadm_sounding_capability;
|
||||
__le16 nadm_random_capability;
|
||||
__u8 cs_sync_phys_supported;
|
||||
__le16 subfeatures_supported;
|
||||
__le16 t_ip1_times_supported;
|
||||
__le16 t_ip2_times_supported;
|
||||
__le16 t_fcs_times_supported;
|
||||
__le16 t_pm_times_supported;
|
||||
__u8 t_sw_time_supported;
|
||||
__u8 tx_snr_capability;
|
||||
} __packed;
|
||||
|
||||
struct hci_rp_le_cs_wr_cached_rmt_supp_cap {
|
||||
__u8 status;
|
||||
__le16 handle;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_SEC_ENABLE 0x208C
|
||||
struct hci_cp_le_cs_sec_enable {
|
||||
__le16 handle;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_SET_DEFAULT_SETTINGS 0x208D
|
||||
struct hci_cp_le_cs_set_default_settings {
|
||||
__le16 handle;
|
||||
__u8 role_enable;
|
||||
__u8 cs_sync_ant_sel;
|
||||
__s8 max_tx_power;
|
||||
} __packed;
|
||||
|
||||
struct hci_rp_le_cs_set_default_settings {
|
||||
__u8 status;
|
||||
__le16 handle;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_RD_RMT_FAE_TABLE 0x208E
|
||||
struct hci_cp_le_cs_rd_rmt_fae_table {
|
||||
__le16 handle;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_WR_CACHED_RMT_FAE_TABLE 0x208F
|
||||
struct hci_cp_le_cs_wr_rmt_cached_fae_table {
|
||||
__le16 handle;
|
||||
__u8 remote_fae_table[72];
|
||||
} __packed;
|
||||
|
||||
struct hci_rp_le_cs_wr_rmt_cached_fae_table {
|
||||
__u8 status;
|
||||
__le16 handle;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_CREATE_CONFIG 0x2090
|
||||
struct hci_cp_le_cs_create_config {
|
||||
__le16 handle;
|
||||
__u8 config_id;
|
||||
__u8 create_context;
|
||||
__u8 main_mode_type;
|
||||
__u8 sub_mode_type;
|
||||
__u8 min_main_mode_steps;
|
||||
__u8 max_main_mode_steps;
|
||||
__u8 main_mode_repetition;
|
||||
__u8 mode_0_steps;
|
||||
__u8 role;
|
||||
__u8 rtt_type;
|
||||
__u8 cs_sync_phy;
|
||||
__u8 channel_map[10];
|
||||
__u8 channel_map_repetition;
|
||||
__u8 channel_selection_type;
|
||||
__u8 ch3c_shape;
|
||||
__u8 ch3c_jump;
|
||||
__u8 reserved;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_REMOVE_CONFIG 0x2091
|
||||
struct hci_cp_le_cs_remove_config {
|
||||
__le16 handle;
|
||||
__u8 config_id;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_SET_CH_CLASSIFICATION 0x2092
|
||||
struct hci_cp_le_cs_set_ch_classification {
|
||||
__u8 ch_classification[10];
|
||||
} __packed;
|
||||
|
||||
struct hci_rp_le_cs_set_ch_classification {
|
||||
__u8 status;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_SET_PROC_PARAM 0x2093
|
||||
struct hci_cp_le_cs_set_proc_param {
|
||||
__le16 handle;
|
||||
__u8 config_id;
|
||||
__le16 max_procedure_len;
|
||||
__le16 min_procedure_interval;
|
||||
__le16 max_procedure_interval;
|
||||
__le16 max_procedure_count;
|
||||
__u8 min_subevent_len[3];
|
||||
__u8 max_subevent_len[3];
|
||||
__u8 tone_antenna_config_selection;
|
||||
__u8 phy;
|
||||
__u8 tx_power_delta;
|
||||
__u8 preferred_peer_antenna;
|
||||
__u8 snr_control_initiator;
|
||||
__u8 snr_control_reflector;
|
||||
} __packed;
|
||||
|
||||
struct hci_rp_le_cs_set_proc_param {
|
||||
__u8 status;
|
||||
__le16 handle;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_SET_PROC_ENABLE 0x2094
|
||||
struct hci_cp_le_cs_set_proc_enable {
|
||||
__le16 handle;
|
||||
__u8 config_id;
|
||||
__u8 enable;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_TEST 0x2095
|
||||
struct hci_cp_le_cs_test {
|
||||
__u8 main_mode_type;
|
||||
__u8 sub_mode_type;
|
||||
__u8 main_mode_repetition;
|
||||
__u8 mode_0_steps;
|
||||
__u8 role;
|
||||
__u8 rtt_type;
|
||||
__u8 cs_sync_phy;
|
||||
__u8 cs_sync_antenna_selection;
|
||||
__u8 subevent_len[3];
|
||||
__le16 subevent_interval;
|
||||
__u8 max_num_subevents;
|
||||
__u8 transmit_power_level;
|
||||
__u8 t_ip1_time;
|
||||
__u8 t_ip2_time;
|
||||
__u8 t_fcs_time;
|
||||
__u8 t_pm_time;
|
||||
__u8 t_sw_time;
|
||||
__u8 tone_antenna_config_selection;
|
||||
__u8 reserved;
|
||||
__u8 snr_control_initiator;
|
||||
__u8 snr_control_reflector;
|
||||
__le16 drbg_nonce;
|
||||
__u8 channel_map_repetition;
|
||||
__le16 override_config;
|
||||
__u8 override_parameters_length;
|
||||
__u8 override_parameters_data[];
|
||||
} __packed;
|
||||
|
||||
struct hci_rp_le_cs_test {
|
||||
__u8 status;
|
||||
} __packed;
|
||||
|
||||
#define HCI_OP_LE_CS_TEST_END 0x2096
|
||||
|
||||
/* ---- HCI Events ---- */
|
||||
struct hci_ev_status {
|
||||
__u8 status;
|
||||
|
|
@ -2960,6 +3169,129 @@ struct hci_evt_le_read_all_remote_features_complete {
|
|||
__u8 features[248];
|
||||
} __packed;
|
||||
|
||||
/* Channel Sounding Events */
|
||||
#define HCI_EVT_LE_CS_READ_RMT_SUPP_CAP_COMPLETE 0x2C
|
||||
struct hci_evt_le_cs_read_rmt_supp_cap_complete {
|
||||
__u8 status;
|
||||
__le16 handle;
|
||||
__u8 num_configs_supp;
|
||||
__le16 max_consec_proc_supp;
|
||||
__u8 num_ant_supp;
|
||||
__u8 max_ant_path_supp;
|
||||
__u8 roles_supp;
|
||||
__u8 modes_supp;
|
||||
__u8 rtt_cap;
|
||||
__u8 rtt_aa_only_n;
|
||||
__u8 rtt_sounding_n;
|
||||
__u8 rtt_rand_payload_n;
|
||||
__le16 nadm_sounding_cap;
|
||||
__le16 nadm_rand_cap;
|
||||
__u8 cs_sync_phys_supp;
|
||||
__le16 sub_feat_supp;
|
||||
__le16 t_ip1_times_supp;
|
||||
__le16 t_ip2_times_supp;
|
||||
__le16 t_fcs_times_supp;
|
||||
__le16 t_pm_times_supp;
|
||||
__u8 t_sw_times_supp;
|
||||
__u8 tx_snr_cap;
|
||||
} __packed;
|
||||
|
||||
#define HCI_EVT_LE_CS_READ_RMT_FAE_TABLE_COMPLETE 0x2D
|
||||
struct hci_evt_le_cs_read_rmt_fae_table_complete {
|
||||
__u8 status;
|
||||
__le16 handle;
|
||||
__u8 remote_fae_table[72];
|
||||
} __packed;
|
||||
|
||||
#define HCI_EVT_LE_CS_SECURITY_ENABLE_COMPLETE 0x2E
|
||||
struct hci_evt_le_cs_security_enable_complete {
|
||||
__u8 status;
|
||||
__le16 handle;
|
||||
} __packed;
|
||||
|
||||
#define HCI_EVT_LE_CS_CONFIG_COMPLETE 0x2F
|
||||
struct hci_evt_le_cs_config_complete {
|
||||
__u8 status;
|
||||
__le16 handle;
|
||||
__u8 config_id;
|
||||
__u8 action;
|
||||
__u8 main_mode_type;
|
||||
__u8 sub_mode_type;
|
||||
__u8 min_main_mode_steps;
|
||||
__u8 max_main_mode_steps;
|
||||
__u8 main_mode_rep;
|
||||
__u8 mode_0_steps;
|
||||
__u8 role;
|
||||
__u8 rtt_type;
|
||||
__u8 cs_sync_phy;
|
||||
__u8 channel_map[10];
|
||||
__u8 channel_map_rep;
|
||||
__u8 channel_sel_type;
|
||||
__u8 ch3c_shape;
|
||||
__u8 ch3c_jump;
|
||||
__u8 reserved;
|
||||
__u8 t_ip1_time;
|
||||
__u8 t_ip2_time;
|
||||
__u8 t_fcs_time;
|
||||
__u8 t_pm_time;
|
||||
} __packed;
|
||||
|
||||
#define HCI_EVT_LE_CS_PROCEDURE_ENABLE_COMPLETE 0x30
|
||||
struct hci_evt_le_cs_procedure_enable_complete {
|
||||
__u8 status;
|
||||
__le16 handle;
|
||||
__u8 config_id;
|
||||
__u8 state;
|
||||
__u8 tone_ant_config_sel;
|
||||
__s8 sel_tx_pwr;
|
||||
__u8 sub_evt_len[3];
|
||||
__u8 sub_evts_per_evt;
|
||||
__le16 sub_evt_intrvl;
|
||||
__le16 evt_intrvl;
|
||||
__le16 proc_intrvl;
|
||||
__le16 proc_counter;
|
||||
__le16 max_proc_len;
|
||||
} __packed;
|
||||
|
||||
#define HCI_EVT_LE_CS_SUBEVENT_RESULT 0x31
|
||||
struct hci_evt_le_cs_subevent_result {
|
||||
__le16 handle;
|
||||
__u8 config_id;
|
||||
__le16 start_acl_conn_evt_counter;
|
||||
__le16 proc_counter;
|
||||
__le16 freq_comp;
|
||||
__u8 ref_pwr_lvl;
|
||||
__u8 proc_done_status;
|
||||
__u8 subevt_done_status;
|
||||
__u8 abort_reason;
|
||||
__u8 num_ant_paths;
|
||||
__u8 num_steps_reported;
|
||||
__u8 step_mode[0]; /* depends on num_steps_reported */
|
||||
__u8 step_channel[0]; /* depends on num_steps_reported */
|
||||
__u8 step_data_length[0]; /* depends on num_steps_reported */
|
||||
__u8 step_data[0]; /* depends on num_steps_reported */
|
||||
} __packed;
|
||||
|
||||
#define HCI_EVT_LE_CS_SUBEVENT_RESULT_CONTINUE 0x32
|
||||
struct hci_evt_le_cs_subevent_result_continue {
|
||||
__le16 handle;
|
||||
__u8 config_id;
|
||||
__u8 proc_done_status;
|
||||
__u8 subevt_done_status;
|
||||
__u8 abort_reason;
|
||||
__u8 num_ant_paths;
|
||||
__u8 num_steps_reported;
|
||||
__u8 step_mode[0]; /* depends on num_steps_reported */
|
||||
__u8 step_channel[0]; /* depends on num_steps_reported */
|
||||
__u8 step_data_length[0]; /* depends on num_steps_reported */
|
||||
__u8 step_data[0]; /* depends on num_steps_reported */
|
||||
} __packed;
|
||||
|
||||
#define HCI_EVT_LE_CS_TEST_END_COMPLETE 0x33
|
||||
struct hci_evt_le_cs_test_end_complete {
|
||||
__u8 status;
|
||||
} __packed;
|
||||
|
||||
#define HCI_EV_VENDOR 0xff
|
||||
|
||||
/* Internal events generated by Bluetooth stack */
|
||||
|
|
|
|||
|
|
@ -730,6 +730,8 @@ struct hci_conn {
|
|||
__u16 le_per_adv_data_offset;
|
||||
__u8 le_adv_phy;
|
||||
__u8 le_adv_sec_phy;
|
||||
__u8 le_tx_def_phys;
|
||||
__u8 le_rx_def_phys;
|
||||
__u8 le_tx_phy;
|
||||
__u8 le_rx_phy;
|
||||
__s8 rssi;
|
||||
|
|
@ -2071,6 +2073,12 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
|
|||
#define ll_ext_feature_capable(dev) \
|
||||
((dev)->le_features[7] & HCI_LE_LL_EXT_FEATURE)
|
||||
|
||||
/* Channel sounding support */
|
||||
#define le_cs_capable(dev) \
|
||||
((dev)->le_features[5] & HCI_LE_CS)
|
||||
#define le_cs_host_capable(dev) \
|
||||
((dev)->le_features[5] & HCI_LE_CS_HOST)
|
||||
|
||||
#define mws_transport_config_capable(dev) (((dev)->commands[30] & 0x08) && \
|
||||
(!hci_test_quirk((dev), HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG)))
|
||||
|
||||
|
|
@ -2334,6 +2342,7 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
|
|||
void *hci_recv_event_data(struct hci_dev *hdev, __u8 event);
|
||||
|
||||
u32 hci_conn_get_phy(struct hci_conn *conn);
|
||||
int hci_conn_set_phy(struct hci_conn *conn, u32 phys);
|
||||
|
||||
/* ----- HCI Sockets ----- */
|
||||
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
|
||||
|
|
|
|||
|
|
@ -191,3 +191,6 @@ int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn);
|
|||
int hci_past_sync(struct hci_conn *conn, struct hci_conn *le);
|
||||
|
||||
int hci_le_read_remote_features(struct hci_conn *conn);
|
||||
|
||||
int hci_acl_change_pkt_type(struct hci_conn *conn, u16 pkt_type);
|
||||
int hci_le_set_phy(struct hci_conn *conn, u8 tx_phys, u8 rx_phys);
|
||||
|
|
|
|||
|
|
@ -655,8 +655,7 @@ struct l2cap_conn {
|
|||
|
||||
struct sk_buff *rx_skb;
|
||||
__u32 rx_len;
|
||||
__u8 tx_ident;
|
||||
struct mutex ident_lock;
|
||||
struct ida tx_ida;
|
||||
|
||||
struct sk_buff_head pending_rx;
|
||||
struct work_struct pending_rx_work;
|
||||
|
|
|
|||
|
|
@ -1002,12 +1002,18 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type,
|
|||
switch (type) {
|
||||
case ACL_LINK:
|
||||
conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
|
||||
conn->link_policy = hdev->link_policy;
|
||||
conn->mtu = hdev->acl_mtu;
|
||||
break;
|
||||
case LE_LINK:
|
||||
/* conn->src should reflect the local identity address */
|
||||
hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
|
||||
conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
|
||||
/* Use the controller supported PHYS as default until the
|
||||
* remote features are resolved.
|
||||
*/
|
||||
conn->le_tx_def_phys = hdev->le_tx_def_phys;
|
||||
conn->le_rx_def_phys = hdev->le_tx_def_phys;
|
||||
break;
|
||||
case CIS_LINK:
|
||||
/* conn->src should reflect the local identity address */
|
||||
|
|
@ -1819,7 +1825,7 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos)
|
|||
cp.bis.sdu = cpu_to_le16(qos->bcast.out.sdu);
|
||||
cp.bis.latency = cpu_to_le16(qos->bcast.out.latency);
|
||||
cp.bis.rtn = qos->bcast.out.rtn;
|
||||
cp.bis.phy = qos->bcast.out.phy;
|
||||
cp.bis.phy = qos->bcast.out.phys;
|
||||
cp.bis.packing = qos->bcast.packing;
|
||||
cp.bis.framing = qos->bcast.framing;
|
||||
cp.bis.encryption = qos->bcast.encryption;
|
||||
|
|
@ -1869,10 +1875,10 @@ static int set_cig_params_sync(struct hci_dev *hdev, void *data)
|
|||
cis->cis_id = cis_id;
|
||||
cis->c_sdu = cpu_to_le16(conn->iso_qos.ucast.out.sdu);
|
||||
cis->p_sdu = cpu_to_le16(conn->iso_qos.ucast.in.sdu);
|
||||
cis->c_phy = qos->ucast.out.phy ? qos->ucast.out.phy :
|
||||
qos->ucast.in.phy;
|
||||
cis->p_phy = qos->ucast.in.phy ? qos->ucast.in.phy :
|
||||
qos->ucast.out.phy;
|
||||
cis->c_phys = qos->ucast.out.phys ? qos->ucast.out.phys :
|
||||
qos->ucast.in.phys;
|
||||
cis->p_phys = qos->ucast.in.phys ? qos->ucast.in.phys :
|
||||
qos->ucast.out.phys;
|
||||
cis->c_rtn = qos->ucast.out.rtn;
|
||||
cis->p_rtn = qos->ucast.in.rtn;
|
||||
}
|
||||
|
|
@ -1974,8 +1980,8 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
|
|||
return cis;
|
||||
|
||||
/* Update LINK PHYs according to QoS preference */
|
||||
cis->le_tx_phy = qos->ucast.out.phy;
|
||||
cis->le_rx_phy = qos->ucast.in.phy;
|
||||
cis->le_tx_phy = qos->ucast.out.phys;
|
||||
cis->le_rx_phy = qos->ucast.in.phys;
|
||||
|
||||
/* If output interval is not set use the input interval as it cannot be
|
||||
* 0x000000.
|
||||
|
|
@ -2090,15 +2096,15 @@ int hci_le_create_cis_pending(struct hci_dev *hdev)
|
|||
}
|
||||
|
||||
static void hci_iso_qos_setup(struct hci_dev *hdev, struct hci_conn *conn,
|
||||
struct bt_iso_io_qos *qos, __u8 phy)
|
||||
struct bt_iso_io_qos *qos, __u8 phys)
|
||||
{
|
||||
/* Only set MTU if PHY is enabled */
|
||||
if (!qos->sdu && qos->phy)
|
||||
if (!qos->sdu && qos->phys)
|
||||
qos->sdu = conn->mtu;
|
||||
|
||||
/* Use the same PHY as ACL if set to any */
|
||||
if (qos->phy == BT_ISO_PHY_ANY)
|
||||
qos->phy = phy;
|
||||
if (qos->phys == BT_ISO_PHY_ANY)
|
||||
qos->phys = phys;
|
||||
|
||||
/* Use LE ACL connection interval if not set */
|
||||
if (!qos->interval)
|
||||
|
|
@ -2118,7 +2124,7 @@ static int create_big_sync(struct hci_dev *hdev, void *data)
|
|||
u32 flags = 0;
|
||||
int err;
|
||||
|
||||
if (qos->bcast.out.phy == 0x02)
|
||||
if (qos->bcast.out.phys == BIT(1))
|
||||
flags |= MGMT_ADV_FLAG_SEC_2M;
|
||||
|
||||
/* Align intervals */
|
||||
|
|
@ -2227,8 +2233,7 @@ struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, __u8 sid,
|
|||
return conn;
|
||||
|
||||
/* Update LINK PHYs according to QoS preference */
|
||||
conn->le_tx_phy = qos->bcast.out.phy;
|
||||
conn->le_tx_phy = qos->bcast.out.phy;
|
||||
conn->le_tx_def_phys = qos->bcast.out.phys;
|
||||
|
||||
/* Add Basic Announcement into Peridic Adv Data if BASE is set */
|
||||
if (base_len && base) {
|
||||
|
|
@ -2237,7 +2242,7 @@ struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, __u8 sid,
|
|||
}
|
||||
|
||||
hci_iso_qos_setup(hdev, conn, &qos->bcast.out,
|
||||
conn->le_tx_phy ? conn->le_tx_phy :
|
||||
conn->le_tx_def_phys ? conn->le_tx_def_phys :
|
||||
hdev->le_tx_def_phys);
|
||||
|
||||
conn->iso_qos = *qos;
|
||||
|
|
@ -2357,9 +2362,11 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
|
|||
return le;
|
||||
|
||||
hci_iso_qos_setup(hdev, le, &qos->ucast.out,
|
||||
le->le_tx_phy ? le->le_tx_phy : hdev->le_tx_def_phys);
|
||||
le->le_tx_def_phys ? le->le_tx_def_phys :
|
||||
hdev->le_tx_def_phys);
|
||||
hci_iso_qos_setup(hdev, le, &qos->ucast.in,
|
||||
le->le_rx_phy ? le->le_rx_phy : hdev->le_rx_def_phys);
|
||||
le->le_rx_def_phys ? le->le_rx_def_phys :
|
||||
hdev->le_rx_def_phys);
|
||||
|
||||
cis = hci_bind_cis(hdev, dst, dst_type, qos, timeout);
|
||||
if (IS_ERR(cis)) {
|
||||
|
|
@ -2614,8 +2621,8 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
|
|||
|
||||
timer:
|
||||
if (hdev->idle_timeout > 0)
|
||||
queue_delayed_work(hdev->workqueue, &conn->idle_work,
|
||||
msecs_to_jiffies(hdev->idle_timeout));
|
||||
mod_delayed_work(hdev->workqueue, &conn->idle_work,
|
||||
msecs_to_jiffies(hdev->idle_timeout));
|
||||
}
|
||||
|
||||
/* Drop all connection on the device */
|
||||
|
|
@ -2928,22 +2935,22 @@ u32 hci_conn_get_phy(struct hci_conn *conn)
|
|||
break;
|
||||
|
||||
case LE_LINK:
|
||||
if (conn->le_tx_phy & HCI_LE_SET_PHY_1M)
|
||||
if (conn->le_tx_def_phys & HCI_LE_SET_PHY_1M)
|
||||
phys |= BT_PHY_LE_1M_TX;
|
||||
|
||||
if (conn->le_rx_phy & HCI_LE_SET_PHY_1M)
|
||||
if (conn->le_rx_def_phys & HCI_LE_SET_PHY_1M)
|
||||
phys |= BT_PHY_LE_1M_RX;
|
||||
|
||||
if (conn->le_tx_phy & HCI_LE_SET_PHY_2M)
|
||||
if (conn->le_tx_def_phys & HCI_LE_SET_PHY_2M)
|
||||
phys |= BT_PHY_LE_2M_TX;
|
||||
|
||||
if (conn->le_rx_phy & HCI_LE_SET_PHY_2M)
|
||||
if (conn->le_rx_def_phys & HCI_LE_SET_PHY_2M)
|
||||
phys |= BT_PHY_LE_2M_RX;
|
||||
|
||||
if (conn->le_tx_phy & HCI_LE_SET_PHY_CODED)
|
||||
if (conn->le_tx_def_phys & HCI_LE_SET_PHY_CODED)
|
||||
phys |= BT_PHY_LE_CODED_TX;
|
||||
|
||||
if (conn->le_rx_phy & HCI_LE_SET_PHY_CODED)
|
||||
if (conn->le_rx_def_phys & HCI_LE_SET_PHY_CODED)
|
||||
phys |= BT_PHY_LE_CODED_RX;
|
||||
|
||||
break;
|
||||
|
|
@ -2952,6 +2959,111 @@ u32 hci_conn_get_phy(struct hci_conn *conn)
|
|||
return phys;
|
||||
}
|
||||
|
||||
static u16 bt_phy_pkt_type(struct hci_conn *conn, u32 phys)
|
||||
{
|
||||
u16 pkt_type = conn->pkt_type;
|
||||
|
||||
if (phys & BT_PHY_BR_1M_3SLOT)
|
||||
pkt_type |= HCI_DM3 | HCI_DH3;
|
||||
else
|
||||
pkt_type &= ~(HCI_DM3 | HCI_DH3);
|
||||
|
||||
if (phys & BT_PHY_BR_1M_5SLOT)
|
||||
pkt_type |= HCI_DM5 | HCI_DH5;
|
||||
else
|
||||
pkt_type &= ~(HCI_DM5 | HCI_DH5);
|
||||
|
||||
if (phys & BT_PHY_EDR_2M_1SLOT)
|
||||
pkt_type &= ~HCI_2DH1;
|
||||
else
|
||||
pkt_type |= HCI_2DH1;
|
||||
|
||||
if (phys & BT_PHY_EDR_2M_3SLOT)
|
||||
pkt_type &= ~HCI_2DH3;
|
||||
else
|
||||
pkt_type |= HCI_2DH3;
|
||||
|
||||
if (phys & BT_PHY_EDR_2M_5SLOT)
|
||||
pkt_type &= ~HCI_2DH5;
|
||||
else
|
||||
pkt_type |= HCI_2DH5;
|
||||
|
||||
if (phys & BT_PHY_EDR_3M_1SLOT)
|
||||
pkt_type &= ~HCI_3DH1;
|
||||
else
|
||||
pkt_type |= HCI_3DH1;
|
||||
|
||||
if (phys & BT_PHY_EDR_3M_3SLOT)
|
||||
pkt_type &= ~HCI_3DH3;
|
||||
else
|
||||
pkt_type |= HCI_3DH3;
|
||||
|
||||
if (phys & BT_PHY_EDR_3M_5SLOT)
|
||||
pkt_type &= ~HCI_3DH5;
|
||||
else
|
||||
pkt_type |= HCI_3DH5;
|
||||
|
||||
return pkt_type;
|
||||
}
|
||||
|
||||
static int bt_phy_le_phy(u32 phys, u8 *tx_phys, u8 *rx_phys)
|
||||
{
|
||||
if (!tx_phys || !rx_phys)
|
||||
return -EINVAL;
|
||||
|
||||
*tx_phys = 0;
|
||||
*rx_phys = 0;
|
||||
|
||||
if (phys & BT_PHY_LE_1M_TX)
|
||||
*tx_phys |= HCI_LE_SET_PHY_1M;
|
||||
|
||||
if (phys & BT_PHY_LE_1M_RX)
|
||||
*rx_phys |= HCI_LE_SET_PHY_1M;
|
||||
|
||||
if (phys & BT_PHY_LE_2M_TX)
|
||||
*tx_phys |= HCI_LE_SET_PHY_2M;
|
||||
|
||||
if (phys & BT_PHY_LE_2M_RX)
|
||||
*rx_phys |= HCI_LE_SET_PHY_2M;
|
||||
|
||||
if (phys & BT_PHY_LE_CODED_TX)
|
||||
*tx_phys |= HCI_LE_SET_PHY_CODED;
|
||||
|
||||
if (phys & BT_PHY_LE_CODED_RX)
|
||||
*rx_phys |= HCI_LE_SET_PHY_CODED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hci_conn_set_phy(struct hci_conn *conn, u32 phys)
|
||||
{
|
||||
u8 tx_phys, rx_phys;
|
||||
|
||||
switch (conn->type) {
|
||||
case SCO_LINK:
|
||||
case ESCO_LINK:
|
||||
return -EINVAL;
|
||||
case ACL_LINK:
|
||||
/* Only allow setting BR/EDR PHYs if link type is ACL */
|
||||
if (phys & ~BT_PHY_BREDR_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
return hci_acl_change_pkt_type(conn,
|
||||
bt_phy_pkt_type(conn, phys));
|
||||
case LE_LINK:
|
||||
/* Only allow setting LE PHYs if link type is LE */
|
||||
if (phys & ~BT_PHY_LE_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
if (bt_phy_le_phy(phys, &tx_phys, &rx_phys))
|
||||
return -EINVAL;
|
||||
|
||||
return hci_le_set_phy(conn, tx_phys, rx_phys);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int abort_conn_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct hci_conn *conn = data;
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ bool hci_discovery_active(struct hci_dev *hdev)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(hci_discovery_active);
|
||||
|
||||
void hci_discovery_set_state(struct hci_dev *hdev, int state)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2869,6 +2869,31 @@ static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)
|
|||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_cs_le_set_phy(struct hci_dev *hdev, u8 status)
|
||||
{
|
||||
struct hci_cp_le_set_phy *cp;
|
||||
struct hci_conn *conn;
|
||||
|
||||
bt_dev_dbg(hdev, "status 0x%2.2x", status);
|
||||
|
||||
if (status)
|
||||
return;
|
||||
|
||||
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PHY);
|
||||
if (!cp)
|
||||
return;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
|
||||
if (conn) {
|
||||
conn->le_tx_def_phys = cp->tx_phys;
|
||||
conn->le_rx_def_phys = cp->rx_phys;
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status)
|
||||
{
|
||||
struct hci_cp_le_read_remote_features *cp;
|
||||
|
|
@ -4359,6 +4384,7 @@ static const struct hci_cs {
|
|||
HCI_CS(HCI_OP_LE_CREATE_CONN, hci_cs_le_create_conn),
|
||||
HCI_CS(HCI_OP_LE_READ_REMOTE_FEATURES, hci_cs_le_read_remote_features),
|
||||
HCI_CS(HCI_OP_LE_START_ENC, hci_cs_le_start_enc),
|
||||
HCI_CS(HCI_OP_LE_SET_PHY, hci_cs_le_set_phy),
|
||||
HCI_CS(HCI_OP_LE_EXT_CREATE_CONN, hci_cs_le_ext_create_conn),
|
||||
HCI_CS(HCI_OP_LE_CREATE_CIS, hci_cs_le_create_cis),
|
||||
HCI_CS(HCI_OP_LE_CREATE_BIG, hci_cs_le_create_big),
|
||||
|
|
@ -6607,8 +6633,20 @@ static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data,
|
|||
|
||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
|
||||
if (conn) {
|
||||
if (!ev->status)
|
||||
memcpy(conn->features[0], ev->features, 8);
|
||||
if (!ev->status) {
|
||||
memcpy(conn->le_features, ev->features, 8);
|
||||
|
||||
/* Update supported PHYs */
|
||||
if (!(conn->le_features[1] & HCI_LE_PHY_2M)) {
|
||||
conn->le_tx_def_phys &= ~HCI_LE_SET_PHY_2M;
|
||||
conn->le_rx_def_phys &= ~HCI_LE_SET_PHY_2M;
|
||||
}
|
||||
|
||||
if (!(conn->le_features[1] & HCI_LE_PHY_CODED)) {
|
||||
conn->le_tx_def_phys &= ~HCI_LE_SET_PHY_CODED;
|
||||
conn->le_rx_def_phys &= ~HCI_LE_SET_PHY_CODED;
|
||||
}
|
||||
}
|
||||
|
||||
if (conn->state == BT_CONFIG) {
|
||||
__u8 status;
|
||||
|
|
@ -6829,6 +6867,21 @@ static void hci_le_phy_update_evt(struct hci_dev *hdev, void *data,
|
|||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
/* Convert LE PHY to QoS PHYs */
|
||||
static u8 le_phy_qos(u8 phy)
|
||||
{
|
||||
switch (phy) {
|
||||
case 0x01:
|
||||
return HCI_LE_SET_PHY_1M;
|
||||
case 0x02:
|
||||
return HCI_LE_SET_PHY_2M;
|
||||
case 0x03:
|
||||
return HCI_LE_SET_PHY_CODED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hci_le_cis_established_evt(struct hci_dev *hdev, void *data,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
|
|
@ -6890,8 +6943,8 @@ static void hci_le_cis_established_evt(struct hci_dev *hdev, void *data,
|
|||
1000);
|
||||
qos->ucast.in.sdu = ev->c_bn ? le16_to_cpu(ev->c_mtu) : 0;
|
||||
qos->ucast.out.sdu = ev->p_bn ? le16_to_cpu(ev->p_mtu) : 0;
|
||||
qos->ucast.in.phy = ev->c_phy;
|
||||
qos->ucast.out.phy = ev->p_phy;
|
||||
qos->ucast.in.phys = le_phy_qos(ev->c_phy);
|
||||
qos->ucast.out.phys = le_phy_qos(ev->p_phy);
|
||||
break;
|
||||
case HCI_ROLE_MASTER:
|
||||
qos->ucast.in.interval = p_sdu_interval;
|
||||
|
|
@ -6905,8 +6958,8 @@ static void hci_le_cis_established_evt(struct hci_dev *hdev, void *data,
|
|||
1000);
|
||||
qos->ucast.out.sdu = ev->c_bn ? le16_to_cpu(ev->c_mtu) : 0;
|
||||
qos->ucast.in.sdu = ev->p_bn ? le16_to_cpu(ev->p_mtu) : 0;
|
||||
qos->ucast.out.phy = ev->c_phy;
|
||||
qos->ucast.in.phy = ev->p_phy;
|
||||
qos->ucast.out.phys = le_phy_qos(ev->c_phy);
|
||||
qos->ucast.in.phys = le_phy_qos(ev->p_phy);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -7221,9 +7274,21 @@ static void hci_le_read_all_remote_features_evt(struct hci_dev *hdev,
|
|||
if (!conn)
|
||||
goto unlock;
|
||||
|
||||
if (!ev->status)
|
||||
if (!ev->status) {
|
||||
memcpy(conn->le_features, ev->features, 248);
|
||||
|
||||
/* Update supported PHYs */
|
||||
if (!(conn->le_features[1] & HCI_LE_PHY_2M)) {
|
||||
conn->le_tx_def_phys &= ~HCI_LE_SET_PHY_2M;
|
||||
conn->le_rx_def_phys &= ~HCI_LE_SET_PHY_2M;
|
||||
}
|
||||
|
||||
if (!(conn->le_features[1] & HCI_LE_PHY_CODED)) {
|
||||
conn->le_tx_def_phys &= ~HCI_LE_SET_PHY_CODED;
|
||||
conn->le_rx_def_phys &= ~HCI_LE_SET_PHY_CODED;
|
||||
}
|
||||
}
|
||||
|
||||
if (conn->state == BT_CONFIG) {
|
||||
__u8 status;
|
||||
|
||||
|
|
|
|||
|
|
@ -2948,8 +2948,8 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
|
|||
if (conn) {
|
||||
struct bt_iso_qos *qos = &conn->iso_qos;
|
||||
|
||||
if (qos->bcast.in.phy & BT_ISO_PHY_1M ||
|
||||
qos->bcast.in.phy & BT_ISO_PHY_2M) {
|
||||
if (qos->bcast.in.phys & BT_ISO_PHY_1M ||
|
||||
qos->bcast.in.phys & BT_ISO_PHY_2M) {
|
||||
cp->scanning_phys |= LE_SCAN_PHY_1M;
|
||||
hci_le_scan_phy_params(phy, type,
|
||||
interval,
|
||||
|
|
@ -2958,7 +2958,7 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
|
|||
phy++;
|
||||
}
|
||||
|
||||
if (qos->bcast.in.phy & BT_ISO_PHY_CODED) {
|
||||
if (qos->bcast.in.phys & BT_ISO_PHY_CODED) {
|
||||
cp->scanning_phys |= LE_SCAN_PHY_CODED;
|
||||
hci_le_scan_phy_params(phy, type,
|
||||
interval * 3,
|
||||
|
|
@ -4428,6 +4428,17 @@ static int hci_le_set_event_mask_sync(struct hci_dev *hdev)
|
|||
events[4] |= 0x02; /* LE BIG Info Advertising Report */
|
||||
}
|
||||
|
||||
if (le_cs_capable(hdev)) {
|
||||
/* Channel Sounding events */
|
||||
events[5] |= 0x08; /* LE CS Read Remote Supported Cap Complete event */
|
||||
events[5] |= 0x10; /* LE CS Read Remote FAE Table Complete event */
|
||||
events[5] |= 0x20; /* LE CS Security Enable Complete event */
|
||||
events[5] |= 0x40; /* LE CS Config Complete event */
|
||||
events[5] |= 0x80; /* LE CS Procedure Enable Complete event */
|
||||
events[6] |= 0x01; /* LE CS Subevent Result event */
|
||||
events[6] |= 0x02; /* LE CS Subevent Result Continue event */
|
||||
events[6] |= 0x04; /* LE CS Test End Complete event */
|
||||
}
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EVENT_MASK,
|
||||
sizeof(events), events, HCI_CMD_TIMEOUT);
|
||||
}
|
||||
|
|
@ -4560,23 +4571,43 @@ static int hci_set_le_support_sync(struct hci_dev *hdev)
|
|||
}
|
||||
|
||||
/* LE Set Host Feature */
|
||||
static int hci_le_set_host_feature_sync(struct hci_dev *hdev)
|
||||
static int hci_le_set_host_feature_sync(struct hci_dev *hdev, u8 bit, u8 value)
|
||||
{
|
||||
struct hci_cp_le_set_host_feature cp;
|
||||
|
||||
if (!iso_capable(hdev))
|
||||
return 0;
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
|
||||
/* Connected Isochronous Channels (Host Support) */
|
||||
cp.bit_number = 32;
|
||||
cp.bit_value = iso_enabled(hdev) ? 0x01 : 0x00;
|
||||
cp.bit_number = bit;
|
||||
cp.bit_value = value;
|
||||
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_HOST_FEATURE,
|
||||
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
|
||||
}
|
||||
|
||||
/* Set Host Features, each feature needs to be sent separately since
|
||||
* HCI_OP_LE_SET_HOST_FEATURE doesn't support setting all of them at once.
|
||||
*/
|
||||
static int hci_le_set_host_features_sync(struct hci_dev *hdev)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (iso_capable(hdev)) {
|
||||
/* Connected Isochronous Channels (Host Support) */
|
||||
err = hci_le_set_host_feature_sync(hdev, 32,
|
||||
(iso_enabled(hdev) ? 0x01 :
|
||||
0x00));
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (le_cs_capable(hdev))
|
||||
/* Channel Sounding (Host Support) */
|
||||
err = hci_le_set_host_feature_sync(hdev, 47, 0x01);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* LE Controller init stage 3 command sequence */
|
||||
static const struct hci_init_stage le_init3[] = {
|
||||
/* HCI_OP_LE_SET_EVENT_MASK */
|
||||
|
|
@ -4604,7 +4635,7 @@ static const struct hci_init_stage le_init3[] = {
|
|||
/* HCI_OP_WRITE_LE_HOST_SUPPORTED */
|
||||
HCI_INIT(hci_set_le_support_sync),
|
||||
/* HCI_OP_LE_SET_HOST_FEATURE */
|
||||
HCI_INIT(hci_le_set_host_feature_sync),
|
||||
HCI_INIT(hci_le_set_host_features_sync),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
@ -6897,8 +6928,6 @@ static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
|
|||
|
||||
conn->attempt++;
|
||||
|
||||
conn->link_policy = hdev->link_policy;
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
bacpy(&cp.bdaddr, &conn->dst);
|
||||
cp.pscan_rep_mode = 0x02;
|
||||
|
|
@ -7419,3 +7448,75 @@ int hci_le_read_remote_features(struct hci_conn *conn)
|
|||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void pkt_type_changed(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct hci_cp_change_conn_ptype *cp = data;
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
kfree(cp);
|
||||
}
|
||||
|
||||
static int hci_change_conn_ptype_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct hci_cp_change_conn_ptype *cp = data;
|
||||
|
||||
return __hci_cmd_sync_status_sk(hdev, HCI_OP_CHANGE_CONN_PTYPE,
|
||||
sizeof(*cp), cp,
|
||||
HCI_EV_PKT_TYPE_CHANGE,
|
||||
HCI_CMD_TIMEOUT, NULL);
|
||||
}
|
||||
|
||||
int hci_acl_change_pkt_type(struct hci_conn *conn, u16 pkt_type)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
struct hci_cp_change_conn_ptype *cp;
|
||||
|
||||
cp = kmalloc(sizeof(*cp), GFP_KERNEL);
|
||||
if (!cp)
|
||||
return -ENOMEM;
|
||||
|
||||
cp->handle = cpu_to_le16(conn->handle);
|
||||
cp->pkt_type = cpu_to_le16(pkt_type);
|
||||
|
||||
return hci_cmd_sync_queue_once(hdev, hci_change_conn_ptype_sync, cp,
|
||||
pkt_type_changed);
|
||||
}
|
||||
|
||||
static void le_phy_update_complete(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
struct hci_cp_le_set_phy *cp = data;
|
||||
|
||||
bt_dev_dbg(hdev, "err %d", err);
|
||||
|
||||
kfree(cp);
|
||||
}
|
||||
|
||||
static int hci_le_set_phy_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct hci_cp_le_set_phy *cp = data;
|
||||
|
||||
return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_SET_PHY,
|
||||
sizeof(*cp), cp,
|
||||
HCI_EV_LE_PHY_UPDATE_COMPLETE,
|
||||
HCI_CMD_TIMEOUT, NULL);
|
||||
}
|
||||
|
||||
int hci_le_set_phy(struct hci_conn *conn, u8 tx_phys, u8 rx_phys)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
struct hci_cp_le_set_phy *cp;
|
||||
|
||||
cp = kmalloc(sizeof(*cp), GFP_KERNEL);
|
||||
if (!cp)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(cp, 0, sizeof(*cp));
|
||||
cp->handle = cpu_to_le16(conn->handle);
|
||||
cp->tx_phys = tx_phys;
|
||||
cp->rx_phys = rx_phys;
|
||||
|
||||
return hci_cmd_sync_queue_once(hdev, hci_le_set_phy_sync, cp,
|
||||
le_phy_update_complete);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ static int iso_connect_bis(struct sock *sk)
|
|||
}
|
||||
|
||||
/* Fail if out PHYs are marked as disabled */
|
||||
if (!iso_pi(sk)->qos.bcast.out.phy) {
|
||||
if (!iso_pi(sk)->qos.bcast.out.phys) {
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
|
@ -458,7 +458,7 @@ static int iso_connect_cis(struct sock *sk)
|
|||
}
|
||||
|
||||
/* Fail if either PHYs are marked as disabled */
|
||||
if (!iso_pi(sk)->qos.ucast.in.phy && !iso_pi(sk)->qos.ucast.out.phy) {
|
||||
if (!iso_pi(sk)->qos.ucast.in.phys && !iso_pi(sk)->qos.ucast.out.phys) {
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
|
@ -894,7 +894,7 @@ static struct proto iso_proto = {
|
|||
.interval = 10000u, \
|
||||
.latency = 10u, \
|
||||
.sdu = 40u, \
|
||||
.phy = BT_ISO_PHY_2M, \
|
||||
.phys = BT_ISO_PHY_2M, \
|
||||
.rtn = 2u, \
|
||||
}
|
||||
|
||||
|
|
@ -1661,7 +1661,7 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
|
|||
static bool check_io_qos(struct bt_iso_io_qos *qos)
|
||||
{
|
||||
/* If no PHY is enable SDU must be 0 */
|
||||
if (!qos->phy && qos->sdu)
|
||||
if (!qos->phys && qos->sdu)
|
||||
return false;
|
||||
|
||||
if (qos->interval && (qos->interval < 0xff || qos->interval > 0xfffff))
|
||||
|
|
@ -1670,7 +1670,7 @@ static bool check_io_qos(struct bt_iso_io_qos *qos)
|
|||
if (qos->latency && (qos->latency < 0x05 || qos->latency > 0xfa0))
|
||||
return false;
|
||||
|
||||
if (qos->phy > BT_ISO_PHY_ANY)
|
||||
if (qos->phys > BT_ISO_PHY_ANY)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -924,26 +924,18 @@ int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator)
|
|||
initiator);
|
||||
}
|
||||
|
||||
static u8 l2cap_get_ident(struct l2cap_conn *conn)
|
||||
static int l2cap_get_ident(struct l2cap_conn *conn)
|
||||
{
|
||||
u8 id;
|
||||
/* LE link does not support tools like l2ping so use the full range */
|
||||
if (conn->hcon->type == LE_LINK)
|
||||
return ida_alloc_range(&conn->tx_ida, 1, 255, GFP_ATOMIC);
|
||||
|
||||
/* Get next available identificator.
|
||||
* 1 - 128 are used by kernel.
|
||||
* 129 - 199 are reserved.
|
||||
* 200 - 254 are used by utilities like l2ping, etc.
|
||||
*/
|
||||
|
||||
mutex_lock(&conn->ident_lock);
|
||||
|
||||
if (++conn->tx_ident > 128)
|
||||
conn->tx_ident = 1;
|
||||
|
||||
id = conn->tx_ident;
|
||||
|
||||
mutex_unlock(&conn->ident_lock);
|
||||
|
||||
return id;
|
||||
return ida_alloc_range(&conn->tx_ida, 1, 128, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
static void l2cap_send_acl(struct l2cap_conn *conn, struct sk_buff *skb,
|
||||
|
|
@ -1773,6 +1765,8 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
|
|||
if (work_pending(&conn->pending_rx_work))
|
||||
cancel_work_sync(&conn->pending_rx_work);
|
||||
|
||||
ida_destroy(&conn->tx_ida);
|
||||
|
||||
cancel_delayed_work_sync(&conn->id_addr_timer);
|
||||
|
||||
l2cap_unregister_all_users(conn);
|
||||
|
|
@ -4782,12 +4776,34 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
|
|||
return err;
|
||||
}
|
||||
|
||||
static void l2cap_put_ident(struct l2cap_conn *conn, u8 code, u8 id)
|
||||
{
|
||||
switch (code) {
|
||||
case L2CAP_COMMAND_REJ:
|
||||
case L2CAP_CONN_RSP:
|
||||
case L2CAP_CONF_RSP:
|
||||
case L2CAP_DISCONN_RSP:
|
||||
case L2CAP_ECHO_RSP:
|
||||
case L2CAP_INFO_RSP:
|
||||
case L2CAP_CONN_PARAM_UPDATE_RSP:
|
||||
case L2CAP_ECRED_CONN_RSP:
|
||||
case L2CAP_ECRED_RECONF_RSP:
|
||||
/* First do a lookup since the remote may send bogus ids that
|
||||
* would make ida_free to generate warnings.
|
||||
*/
|
||||
if (ida_find_first_range(&conn->tx_ida, id, id) >= 0)
|
||||
ida_free(&conn->tx_ida, id);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||
u8 *data)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
l2cap_put_ident(conn, cmd->code, cmd->ident);
|
||||
|
||||
switch (cmd->code) {
|
||||
case L2CAP_COMMAND_REJ:
|
||||
l2cap_command_rej(conn, cmd, cmd_len, data);
|
||||
|
|
@ -5419,6 +5435,8 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
|
|||
{
|
||||
int err = 0;
|
||||
|
||||
l2cap_put_ident(conn, cmd->code, cmd->ident);
|
||||
|
||||
switch (cmd->code) {
|
||||
case L2CAP_COMMAND_REJ:
|
||||
l2cap_le_command_rej(conn, cmd, cmd_len, data);
|
||||
|
|
@ -6907,13 +6925,13 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
|
|||
hci_dev_test_flag(hcon->hdev, HCI_FORCE_BREDR_SMP)))
|
||||
conn->local_fixed_chan |= L2CAP_FC_SMP_BREDR;
|
||||
|
||||
mutex_init(&conn->ident_lock);
|
||||
mutex_init(&conn->lock);
|
||||
|
||||
INIT_LIST_HEAD(&conn->chan_l);
|
||||
INIT_LIST_HEAD(&conn->users);
|
||||
|
||||
INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
|
||||
ida_init(&conn->tx_ida);
|
||||
|
||||
skb_queue_head_init(&conn->pending_rx);
|
||||
INIT_WORK(&conn->pending_rx_work, process_pending_rx);
|
||||
|
|
|
|||
|
|
@ -885,7 +885,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
|||
struct bt_power pwr;
|
||||
struct l2cap_conn *conn;
|
||||
int err = 0;
|
||||
u32 opt;
|
||||
u32 opt, phys;
|
||||
u16 mtu;
|
||||
u8 mode;
|
||||
|
||||
|
|
@ -1059,6 +1059,24 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
|||
|
||||
break;
|
||||
|
||||
case BT_PHY:
|
||||
if (sk->sk_state != BT_CONNECTED) {
|
||||
err = -ENOTCONN;
|
||||
break;
|
||||
}
|
||||
|
||||
err = copy_safe_from_sockptr(&phys, sizeof(phys), optval,
|
||||
optlen);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
if (!chan->conn)
|
||||
break;
|
||||
|
||||
conn = chan->conn;
|
||||
err = hci_conn_set_phy(conn->hcon, phys);
|
||||
break;
|
||||
|
||||
case BT_MODE:
|
||||
if (!enable_ecred) {
|
||||
err = -ENOPROTOOPT;
|
||||
|
|
|
|||
|
|
@ -1966,6 +1966,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
|
|||
}
|
||||
|
||||
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
||||
mgmt_pending_free(cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1984,6 +1985,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
|
|||
sock_put(match.sk);
|
||||
|
||||
hci_update_eir_sync(hdev);
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static int set_ssp_sync(struct hci_dev *hdev, void *data)
|
||||
|
|
@ -6438,6 +6440,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
|
|||
hci_dev_clear_flag(hdev, HCI_ADVERTISING);
|
||||
|
||||
settings_rsp(cmd, &match);
|
||||
mgmt_pending_free(cmd);
|
||||
|
||||
new_settings(hdev, match.sk);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,12 @@
|
|||
#include "mgmt_util.h"
|
||||
#include "mgmt_config.h"
|
||||
|
||||
#define HDEV_PARAM_U32(_param_name_) \
|
||||
struct {\
|
||||
struct mgmt_tlv_hdr entry; \
|
||||
__le32 value; \
|
||||
} __packed _param_name_
|
||||
|
||||
#define HDEV_PARAM_U16(_param_name_) \
|
||||
struct {\
|
||||
struct mgmt_tlv_hdr entry; \
|
||||
|
|
@ -29,6 +35,12 @@
|
|||
cpu_to_le16(hdev->_param_name_) \
|
||||
}
|
||||
|
||||
#define TLV_SET_U32(_param_code_, _param_name_) \
|
||||
{ \
|
||||
{ cpu_to_le16(_param_code_), sizeof(__u32) }, \
|
||||
cpu_to_le32(hdev->_param_name_) \
|
||||
}
|
||||
|
||||
#define TLV_SET_U8(_param_code_, _param_name_) \
|
||||
{ \
|
||||
{ cpu_to_le16(_param_code_), sizeof(__u8) }, \
|
||||
|
|
@ -78,6 +90,7 @@ int read_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
HDEV_PARAM_U16(advmon_allowlist_duration);
|
||||
HDEV_PARAM_U16(advmon_no_filter_duration);
|
||||
HDEV_PARAM_U8(enable_advmon_interleave_scan);
|
||||
HDEV_PARAM_U32(idle_timeout);
|
||||
} __packed rp = {
|
||||
TLV_SET_U16(0x0000, def_page_scan_type),
|
||||
TLV_SET_U16(0x0001, def_page_scan_int),
|
||||
|
|
@ -111,6 +124,7 @@ int read_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
TLV_SET_U16(0x001d, advmon_allowlist_duration),
|
||||
TLV_SET_U16(0x001e, advmon_no_filter_duration),
|
||||
TLV_SET_U8(0x001f, enable_advmon_interleave_scan),
|
||||
TLV_SET_U32(0x0020, idle_timeout),
|
||||
};
|
||||
|
||||
bt_dev_dbg(hdev, "sock %p", sk);
|
||||
|
|
@ -122,6 +136,7 @@ int read_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
}
|
||||
|
||||
#define TO_TLV(x) ((struct mgmt_tlv *)(x))
|
||||
#define TLV_GET_LE32(tlv) le32_to_cpu(*((__le32 *)(TO_TLV(tlv)->value)))
|
||||
#define TLV_GET_LE16(tlv) le16_to_cpu(*((__le16 *)(TO_TLV(tlv)->value)))
|
||||
#define TLV_GET_U8(tlv) (*((__u8 *)(TO_TLV(tlv)->value)))
|
||||
|
||||
|
|
@ -191,6 +206,9 @@ int set_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
case 0x001f:
|
||||
exp_type_len = sizeof(u8);
|
||||
break;
|
||||
case 0x0020:
|
||||
exp_type_len = sizeof(u32);
|
||||
break;
|
||||
default:
|
||||
exp_type_len = 0;
|
||||
bt_dev_warn(hdev, "unsupported parameter %u", type);
|
||||
|
|
@ -314,6 +332,9 @@ int set_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
case 0x0001f:
|
||||
hdev->enable_advmon_interleave_scan = TLV_GET_U8(buffer);
|
||||
break;
|
||||
case 0x00020:
|
||||
hdev->idle_timeout = TLV_GET_LE32(buffer);
|
||||
break;
|
||||
default:
|
||||
bt_dev_warn(hdev, "unsupported parameter %u", type);
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user