Hi Luiz, I have re-sent this patch. Can you please review this? Thank you for your time. Thanks, Neeraj > This handles the timeout errors seen in the bootloader signatures during FW > download. > > When the bootloader does not receive a response packet from the host > within a specific time, it adds an error code to the bootloader signature while > requesting for the FW chunk from the same offset. > > The host is expected to clear this error code with a NAK, and reply to only > those bootloader signatures which have error code 0. > > This error handling is valid for data_req bootloader signatures for V3 and > future bootloader versions. > > Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@xxxxxxx> > --- > drivers/bluetooth/btnxpuart.c | 46 ++++++++++++++++++++++++++++++++--- > 1 file changed, 42 insertions(+), 4 deletions(-) > > diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c > index 0b93c2ff29e4..2018513fb961 100644 > --- a/drivers/bluetooth/btnxpuart.c > +++ b/drivers/bluetooth/btnxpuart.c > @@ -187,6 +187,10 @@ struct btnxpuart_dev { > #define NXP_NAK_V3 0x7b > #define NXP_CRC_ERROR_V3 0x7c > > +#define NXP_ACK_RX_TIMEOUT 0x0002 > +#define NXP_HDR_RX_TIMEOUT 0x0003 > +#define NXP_DATA_RX_TIMEOUT 0x0004 > + > #define HDR_LEN 16 > > #define NXP_RECV_CHIP_VER_V1 \ > @@ -277,6 +281,12 @@ struct nxp_bootloader_cmd { > __be32 crc; > } __packed; > > +struct nxp_v3_rx_timeout_nak { > + u8 nak; > + __le32 offset; > + u8 crc; > +} __packed; > + > static u8 crc8_table[CRC8_TABLE_SIZE]; > > /* Default configurations */ > @@ -899,6 +909,32 @@ static int nxp_recv_chip_ver_v3(struct hci_dev *hdev, > struct sk_buff *skb) > return 0; > } > > +static void nxp_handle_fw_dnld_error(struct hci_dev *hdev, struct > +v3_data_req *req) { > + struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev); > + __u32 offset = __le32_to_cpu(req->offset); > + __u16 err = __le16_to_cpu(req->error); > + struct nxp_v3_rx_timeout_nak nak_tx_buf; > + > + switch (err) { > + case NXP_ACK_RX_TIMEOUT: > + case NXP_HDR_RX_TIMEOUT: > + case NXP_DATA_RX_TIMEOUT: > + nak_tx_buf.nak = NXP_NAK_V3; > + nak_tx_buf.offset = __cpu_to_le32(offset); > + nak_tx_buf.crc = crc8(crc8_table, (u8 *)&nak_tx_buf, > + sizeof(nak_tx_buf) - 1, 0xff); > + serdev_device_write_buf(nxpdev->serdev, (u8 > *)&nak_tx_buf, > + sizeof(nak_tx_buf)); > + break; > + default: > + bt_dev_dbg(hdev, "Unknown bootloader error: %d", err); > + break; > + > + } > + > +} > + > static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb) { > struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev); @@ -913,7 > +949,12 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct > sk_buff *skb) > if (!req || !nxpdev->fw) > goto free_skb; > > - nxp_send_ack(NXP_ACK_V3, hdev); > + if (!req->error) { > + nxp_send_ack(NXP_ACK_V3, hdev); > + } else { > + nxp_handle_fw_dnld_error(hdev, req); > + goto free_skb; > + } > > len = __le16_to_cpu(req->len); > > @@ -940,9 +981,6 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, > struct sk_buff *skb) > wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q); > goto free_skb; > } > - if (req->error) > - bt_dev_dbg(hdev, "FW Download received err 0x%02x from > chip", > - req->error); > > offset = __le32_to_cpu(req->offset); > if (offset < nxpdev->fw_v3_offset_correction) { > -- > 2.34.1