diff mbox series

[v2,2/2] Bluetooth: btnxpuart: Add support for set BD address

Message ID 20250114133548.2362038-2-neeraj.sanjaykale@nxp.com (mailing list archive)
State Superseded
Headers show
Series [v2,1/2] dt-bindings: net: bluetooth: nxp: Add support to set BD address | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/SubjectPrefix success Gitlint PASS

Commit Message

Neeraj Sanjay Kale Jan. 14, 2025, 1:35 p.m. UTC
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.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: Johan Korsnes <johan.korsnes@remarkable.no>
Signed-off-by: Kristian Husevåg Krohn <kristian.krohn@remarkable.no>
Tested-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
 drivers/bluetooth/btnxpuart.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

Comments

Johan Korsnes Jan. 14, 2025, 1:53 p.m. UTC | #1
On 1/14/25 2:35 PM, Neeraj Sanjay Kale 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.
>

Hi Neeraj,

If NXP firmware does not allow vendor commands prior to this reset, would
it not be better to perform this reset during probe/init?

Kind regards,
Johan
Neeraj Sanjay Kale Jan. 14, 2025, 2:07 p.m. UTC | #2
Hi Johan,

> 
> On 1/14/25 2:35 PM, Neeraj Sanjay Kale 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.
> >
> 
> Hi Neeraj,
> 
> If NXP firmware does not allow vendor commands prior to this reset, would it
> not be better to perform this reset during probe/init?
>
HCI reset is already part of kernel init sequence hci_init0_sync().
However, .set_bdaddr() is called immediately after FW download is complete, but before this init sequence.

Also, if local-bd-address property is not defined in the DTB, sending HCI reset command in probe does not add any value.

With current implementation, if local-bd-address is defined, driver sends HCI reset, followed by set BD address vendor command, and kernel continues with the HCI init sequence.

Thanks,
Neeraj
Johan Korsnes Jan. 14, 2025, 2:09 p.m. UTC | #3
On 1/14/25 3:07 PM, Neeraj Sanjay Kale wrote:
> 
> Hi Johan,
> 
>>
>> On 1/14/25 2:35 PM, Neeraj Sanjay Kale 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.
>>>
>>
>> Hi Neeraj,
>>
>> If NXP firmware does not allow vendor commands prior to this reset, would it
>> not be better to perform this reset during probe/init?
>>
> HCI reset is already part of kernel init sequence hci_init0_sync().
> However, .set_bdaddr() is called immediately after FW download is complete, but before this init sequence.
> 
> Also, if local-bd-address property is not defined in the DTB, sending HCI reset command in probe does not add any value.
> 
> With current implementation, if local-bd-address is defined, driver sends HCI reset, followed by set BD address vendor command, and kernel continues with the HCI init sequence.
>

Thanks for clarifying, that makes sense :-)

Kind regards,
Johan

> Thanks,
> Neeraj
diff mbox series

Patch

diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 1230045d78a5..deb546a4e664 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -1197,6 +1197,34 @@  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)
+{
+	u8 data[8] = { 0xfe, 0x06, 0, 0, 0, 0, 0, 0 };
+	struct sk_buff *skb;
+	int err;
+
+	memcpy(data + 2, bdaddr, 6);
+
+	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, 0xfc22, sizeof(data), data, 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)
 {
@@ -1547,8 +1575,12 @@  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);
 
+	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;