devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 1/2] dt-bindings: net: bluetooth: nxp: Add support to set BD address
@ 2025-02-28 15:29 Neeraj Sanjay Kale
  2025-02-28 15:29 ` [PATCH v6 2/2] Bluetooth: btnxpuart: " Neeraj Sanjay Kale
  0 siblings, 1 reply; 4+ messages in thread
From: Neeraj Sanjay Kale @ 2025-02-28 15:29 UTC (permalink / raw)
  To: marcel, luiz.dentz, robh, krzk+dt, conor+dt
  Cc: linux-bluetooth, linux-kernel, devicetree, amitkumar.karwar,
	neeraj.sanjaykale, sherry.sun, ziniu.wang_1, johan.korsnes,
	kristian.krohn, manjeet.gupta

Allow user to set custom BD address for NXP chipsets.

Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
v2: Add allOf and unevaluatedProperties: false (Krzysztof)
v3: Drop local-bd-address: true (Krzysztof)
---
 .../devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml   | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml b/Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml
index 0a2d7baf5db3..a84c1c21b024 100644
--- a/Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml
+++ b/Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml
@@ -17,6 +17,9 @@ description:
 maintainers:
   - Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
 
+allOf:
+  - $ref: bluetooth-controller.yaml#
+
 properties:
   compatible:
     enum:
@@ -43,7 +46,7 @@ properties:
 required:
   - compatible
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |
@@ -54,5 +57,6 @@ examples:
             fw-init-baudrate = <3000000>;
             firmware-name = "uartuart8987_bt_v0.bin";
             device-wakeup-gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+            local-bd-address = [66 55 44 33 22 11];
         };
     };
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v6 2/2] Bluetooth: btnxpuart: Add support to set BD address
  2025-02-28 15:29 [PATCH v6 1/2] dt-bindings: net: bluetooth: nxp: Add support to set BD address Neeraj Sanjay Kale
@ 2025-02-28 15:29 ` Neeraj Sanjay Kale
  2025-02-28 15:41   ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 4+ messages in thread
From: Neeraj Sanjay Kale @ 2025-02-28 15:29 UTC (permalink / raw)
  To: marcel, luiz.dentz, robh, krzk+dt, conor+dt
  Cc: linux-bluetooth, linux-kernel, devicetree, amitkumar.karwar,
	neeraj.sanjaykale, sherry.sun, ziniu.wang_1, johan.korsnes,
	kristian.krohn, manjeet.gupta

This adds support for setting BD address during hci registration. NXP
FW does not allow vendor commands unless it receives a reset command
after FW download and initialization done.

As a workaround, the .set_bdaddr callback function will first send the
HCI reset command, followed by the actual vendor command to set BD
address.

The driver checks for the local-bd-address property in device tree, and
if preset, it sets the HCI_QUIRK_USE_BDADDR_PROPERTY quirk.

With this quirk set, the driver's set_bdaddr callback function is called
after FW download is complete and before HCI initialization, which sends
the hci reset and 3f 22 commands. During initialization, kernel reads
the newly set BD address from the controller.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: Johan Korsnes <johan.korsnes@remarkable.no>
Signed-off-by: Kristian Krohn <kristian.krohn@remarkable.no>
Tested-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
v4: hci0 interface shows RAW mode if 'local-bd-address' not defined and
    HCI_QUIRK_USE_BDADDR_PROPERTY is set. Add Quirk only if device tree
    property 'local-bd-address' found. (Neeraj)
v5: Initialize local variable ba, update Copywrite year. (Kristian)
v6: Elaborate commit message, add User Manual reference. (Paul Menzel)
---
 drivers/bluetooth/btnxpuart.c | 63 ++++++++++++++++++++++++++++++++---
 1 file changed, 58 insertions(+), 5 deletions(-)

diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 1230045d78a5..2eb14b9beb70 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
  *  NXP Bluetooth driver
- *  Copyright 2023 NXP
+ *  Copyright 2023-2025 NXP
  */
 
 #include <linux/module.h>
@@ -98,13 +98,16 @@
 #define PS_STATE_AWAKE          0
 #define PS_STATE_SLEEP          1
 
-/* Bluetooth vendor command : Sleep mode */
+/* NXP Vendor Commands. Refer user manual UM11628 on nxp.com */
+/* Set custom BD Address */
+#define HCI_NXP_SET_BD_ADDR	0xfc22
+/* Set Auto-Sleep mode */
 #define HCI_NXP_AUTO_SLEEP_MODE	0xfc23
-/* Bluetooth vendor command : Wakeup method */
+/* Set Wakeup method */
 #define HCI_NXP_WAKEUP_METHOD	0xfc53
-/* Bluetooth vendor command : Set operational baudrate */
+/* Set operational baudrate */
 #define HCI_NXP_SET_OPER_SPEED	0xfc09
-/* Bluetooth vendor command: Independent Reset */
+/* Independent Reset (Soft Reset) */
 #define HCI_NXP_IND_RESET	0xfcfc
 
 /* Bluetooth Power State : Vendor cmd params */
@@ -310,6 +313,15 @@ union nxp_v3_rx_timeout_nak_u {
 	u8 buf[6];
 };
 
+union nxp_set_bd_addr_payload {
+	struct {
+		u8 param_id;
+		u8 param_len;
+		u8 param[6];
+	} __packed data;
+	u8 buf[8];
+};
+
 static u8 crc8_table[CRC8_TABLE_SIZE];
 
 /* Default configurations */
@@ -1197,6 +1209,38 @@ static int nxp_set_ind_reset(struct hci_dev *hdev, void *data)
 	return hci_recv_frame(hdev, skb);
 }
 
+static int nxp_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+	union nxp_set_bd_addr_payload pcmd;
+	struct sk_buff *skb;
+	int err;
+
+	pcmd.data.param_id = 0xfe;
+	pcmd.data.param_len = 6;
+	memcpy(pcmd.data.param, bdaddr, 6);
+
+	/* BD address can be assigned only after first reset command. */
+	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		err = PTR_ERR(skb);
+		bt_dev_err(hdev, "Reset before setting local-bd-addr failed (%ld)",
+			   PTR_ERR(skb));
+		return err;
+	}
+	kfree_skb(skb);
+
+	skb = __hci_cmd_sync(hdev, HCI_NXP_SET_BD_ADDR, sizeof(pcmd),
+			     pcmd.buf, HCI_CMD_TIMEOUT);
+	if (IS_ERR(skb)) {
+		err = PTR_ERR(skb);
+		bt_dev_err(hdev, "Changing device address failed (%d)", err);
+		return err;
+	}
+	kfree_skb(skb);
+
+	return 0;
+}
+
 /* NXP protocol */
 static int nxp_setup(struct hci_dev *hdev)
 {
@@ -1500,6 +1544,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
 {
 	struct hci_dev *hdev;
 	struct btnxpuart_dev *nxpdev;
+	bdaddr_t ba = {0};
 
 	nxpdev = devm_kzalloc(&serdev->dev, sizeof(*nxpdev), GFP_KERNEL);
 	if (!nxpdev)
@@ -1547,8 +1592,16 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
 	hdev->send  = nxp_enqueue;
 	hdev->hw_error = nxp_hw_err;
 	hdev->shutdown = nxp_shutdown;
+	hdev->set_bdaddr = nxp_set_bdaddr;
+
 	SET_HCIDEV_DEV(hdev, &serdev->dev);
 
+	device_property_read_u8_array(&nxpdev->serdev->dev,
+				      "local-bd-address",
+				      (u8 *)&ba, sizeof(ba));
+	if (bacmp(&ba, BDADDR_ANY))
+		set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
+
 	if (hci_register_dev(hdev) < 0) {
 		dev_err(&serdev->dev, "Can't register HCI device\n");
 		goto probe_fail;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v6 2/2] Bluetooth: btnxpuart: Add support to set BD address
  2025-02-28 15:29 ` [PATCH v6 2/2] Bluetooth: btnxpuart: " Neeraj Sanjay Kale
@ 2025-02-28 15:41   ` Luiz Augusto von Dentz
  2025-03-03  9:24     ` Neeraj Sanjay Kale
  0 siblings, 1 reply; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2025-02-28 15:41 UTC (permalink / raw)
  To: Neeraj Sanjay Kale
  Cc: marcel, robh, krzk+dt, conor+dt, linux-bluetooth, linux-kernel,
	devicetree, amitkumar.karwar, sherry.sun, ziniu.wang_1,
	johan.korsnes, kristian.krohn, manjeet.gupta

Hi Neeraj,

On Fri, Feb 28, 2025 at 10:27 AM Neeraj Sanjay Kale
<neeraj.sanjaykale@nxp.com> wrote:
>
> This adds support for setting BD address during hci registration. NXP
> FW does not allow vendor commands unless it receives a reset command
> after FW download and initialization done.
>
> As a workaround, the .set_bdaddr callback function will first send the
> HCI reset command, followed by the actual vendor command to set BD
> address.
>
> The driver checks for the local-bd-address property in device tree, and
> if preset, it sets the HCI_QUIRK_USE_BDADDR_PROPERTY quirk.
>
> With this quirk set, the driver's set_bdaddr callback function is called
> after FW download is complete and before HCI initialization, which sends
> the hci reset and 3f 22 commands. During initialization, kernel reads
> the newly set BD address from the controller.
>
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> Signed-off-by: Johan Korsnes <johan.korsnes@remarkable.no>
> Signed-off-by: Kristian Krohn <kristian.krohn@remarkable.no>
> Tested-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
> Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
> ---
> v4: hci0 interface shows RAW mode if 'local-bd-address' not defined and
>     HCI_QUIRK_USE_BDADDR_PROPERTY is set. Add Quirk only if device tree
>     property 'local-bd-address' found. (Neeraj)
> v5: Initialize local variable ba, update Copywrite year. (Kristian)
> v6: Elaborate commit message, add User Manual reference. (Paul Menzel)
> ---
>  drivers/bluetooth/btnxpuart.c | 63 ++++++++++++++++++++++++++++++++---
>  1 file changed, 58 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
> index 1230045d78a5..2eb14b9beb70 100644
> --- a/drivers/bluetooth/btnxpuart.c
> +++ b/drivers/bluetooth/btnxpuart.c
> @@ -1,7 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0-or-later
>  /*
>   *  NXP Bluetooth driver
> - *  Copyright 2023 NXP
> + *  Copyright 2023-2025 NXP
>   */
>
>  #include <linux/module.h>
> @@ -98,13 +98,16 @@
>  #define PS_STATE_AWAKE          0
>  #define PS_STATE_SLEEP          1
>
> -/* Bluetooth vendor command : Sleep mode */
> +/* NXP Vendor Commands. Refer user manual UM11628 on nxp.com */
> +/* Set custom BD Address */
> +#define HCI_NXP_SET_BD_ADDR    0xfc22
> +/* Set Auto-Sleep mode */
>  #define HCI_NXP_AUTO_SLEEP_MODE        0xfc23
> -/* Bluetooth vendor command : Wakeup method */
> +/* Set Wakeup method */
>  #define HCI_NXP_WAKEUP_METHOD  0xfc53
> -/* Bluetooth vendor command : Set operational baudrate */
> +/* Set operational baudrate */
>  #define HCI_NXP_SET_OPER_SPEED 0xfc09
> -/* Bluetooth vendor command: Independent Reset */
> +/* Independent Reset (Soft Reset) */
>  #define HCI_NXP_IND_RESET      0xfcfc
>
>  /* Bluetooth Power State : Vendor cmd params */
> @@ -310,6 +313,15 @@ union nxp_v3_rx_timeout_nak_u {
>         u8 buf[6];
>  };
>
> +union nxp_set_bd_addr_payload {
> +       struct {
> +               u8 param_id;
> +               u8 param_len;
> +               u8 param[6];
> +       } __packed data;
> +       u8 buf[8];
> +};
> +
>  static u8 crc8_table[CRC8_TABLE_SIZE];
>
>  /* Default configurations */
> @@ -1197,6 +1209,38 @@ static int nxp_set_ind_reset(struct hci_dev *hdev, void *data)
>         return hci_recv_frame(hdev, skb);
>  }
>
> +static int nxp_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
> +{
> +       union nxp_set_bd_addr_payload pcmd;
> +       struct sk_buff *skb;
> +       int err;
> +
> +       pcmd.data.param_id = 0xfe;
> +       pcmd.data.param_len = 6;
> +       memcpy(pcmd.data.param, bdaddr, 6);
> +
> +       /* BD address can be assigned only after first reset command. */
> +       skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
> +       if (IS_ERR(skb)) {
> +               err = PTR_ERR(skb);
> +               bt_dev_err(hdev, "Reset before setting local-bd-addr failed (%ld)",
> +                          PTR_ERR(skb));
> +               return err;
> +       }
> +       kfree_skb(skb);

If you don't care about the response, just the status, it is probably
better to use __hci_cmd_sync_status, also since the hdev->set_bdaddr
comes after hdev->setup doesn't the later do perform a reset anyway?
If you end up with 2 resets in a row it problems means you don't need
to reset again.

> +
> +       skb = __hci_cmd_sync(hdev, HCI_NXP_SET_BD_ADDR, sizeof(pcmd),
> +                            pcmd.buf, HCI_CMD_TIMEOUT);

Ditto.

> +       if (IS_ERR(skb)) {
> +               err = PTR_ERR(skb);
> +               bt_dev_err(hdev, "Changing device address failed (%d)", err);
> +               return err;
> +       }
> +       kfree_skb(skb);
> +
> +       return 0;
> +}
> +
>  /* NXP protocol */
>  static int nxp_setup(struct hci_dev *hdev)
>  {
> @@ -1500,6 +1544,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
>  {
>         struct hci_dev *hdev;
>         struct btnxpuart_dev *nxpdev;
> +       bdaddr_t ba = {0};
>
>         nxpdev = devm_kzalloc(&serdev->dev, sizeof(*nxpdev), GFP_KERNEL);
>         if (!nxpdev)
> @@ -1547,8 +1592,16 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
>         hdev->send  = nxp_enqueue;
>         hdev->hw_error = nxp_hw_err;
>         hdev->shutdown = nxp_shutdown;
> +       hdev->set_bdaddr = nxp_set_bdaddr;
> +
>         SET_HCIDEV_DEV(hdev, &serdev->dev);
>
> +       device_property_read_u8_array(&nxpdev->serdev->dev,
> +                                     "local-bd-address",
> +                                     (u8 *)&ba, sizeof(ba));
> +       if (bacmp(&ba, BDADDR_ANY))
> +               set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
> +
>         if (hci_register_dev(hdev) < 0) {
>                 dev_err(&serdev->dev, "Can't register HCI device\n");
>                 goto probe_fail;
> --
> 2.25.1
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v6 2/2] Bluetooth: btnxpuart: Add support to set BD address
  2025-02-28 15:41   ` Luiz Augusto von Dentz
@ 2025-03-03  9:24     ` Neeraj Sanjay Kale
  0 siblings, 0 replies; 4+ messages in thread
From: Neeraj Sanjay Kale @ 2025-03-03  9:24 UTC (permalink / raw)
  To: Luiz Augusto von Dentz
  Cc: marcel@holtmann.org, robh@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org, linux-bluetooth@vger.kernel.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	Amitkumar Karwar, Sherry Sun, Luke Wang,
	johan.korsnes@remarkable.no, kristian.krohn@remarkable.no,
	Manjeet Gupta

Hi Luiz,

Thank you for reviewing the patch.

> > @@ -1197,6 +1209,38 @@ static int nxp_set_ind_reset(struct hci_dev
> *hdev, void *data)
> >         return hci_recv_frame(hdev, skb);  }
> >
> > +static int nxp_set_bdaddr(struct hci_dev *hdev, const bdaddr_t
> > +*bdaddr) {
> > +       union nxp_set_bd_addr_payload pcmd;
> > +       struct sk_buff *skb;
> > +       int err;
> > +
> > +       pcmd.data.param_id = 0xfe;
> > +       pcmd.data.param_len = 6;
> > +       memcpy(pcmd.data.param, bdaddr, 6);
> > +
> > +       /* BD address can be assigned only after first reset command. */
> > +       skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
> HCI_INIT_TIMEOUT);
> > +       if (IS_ERR(skb)) {
> > +               err = PTR_ERR(skb);
> > +               bt_dev_err(hdev, "Reset before setting local-bd-addr failed (%ld)",
> > +                          PTR_ERR(skb));
> > +               return err;
> > +       }
> > +       kfree_skb(skb);
> 
> If you don't care about the response, just the status, it is probably better to
> use __hci_cmd_sync_status, also since the hdev->set_bdaddr comes after
> hdev->setup doesn't the later do perform a reset anyway?
> If you end up with 2 resets in a row it problems means you don't need to
> reset again.

Hdev->set_bdaddr comes after hdev->setup, but comes before the first HCI RESET.

With this patch, if Device Tree has a local-bd-addr property, hdev->set_bdaddr will send HCI RESET, followed by 3f22 command, and then HCI RESET again during initialization, along with READ LOCAL FEATURES, READ LOCAL VERSION and READ BD ADDR. 

Without local-bd-addr DT property, hdev->set_bdaddr will be skipped and only one HCI RESET will be sent.
> 
> > +
> > +       skb = __hci_cmd_sync(hdev, HCI_NXP_SET_BD_ADDR, sizeof(pcmd),
> > +                            pcmd.buf, HCI_CMD_TIMEOUT);
> 
> Ditto.
> 
> > +       if (IS_ERR(skb)) {
> > +               err = PTR_ERR(skb);
> > +               bt_dev_err(hdev, "Changing device address failed (%d)", err);
> > +               return err;
> > +       }
> > +       kfree_skb(skb);
> > +
> > +       return 0;
> > +}
> > +
> >  /* NXP protocol */

Thanks,
Neeraj

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-03-03  9:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-28 15:29 [PATCH v6 1/2] dt-bindings: net: bluetooth: nxp: Add support to set BD address Neeraj Sanjay Kale
2025-02-28 15:29 ` [PATCH v6 2/2] Bluetooth: btnxpuart: " Neeraj Sanjay Kale
2025-02-28 15:41   ` Luiz Augusto von Dentz
2025-03-03  9:24     ` Neeraj Sanjay Kale

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).