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 |
Context | Check | Description |
---|---|---|
tedd_an/pre-ci_am | success | Success |
tedd_an/SubjectPrefix | success | Gitlint PASS |
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
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
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 --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;