]> www.infradead.org Git - users/hch/misc.git/commitdiff
Bluetooth: btnxpuart: Add correct bootloader error codes
authorNeeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Mon, 10 Mar 2025 12:02:29 +0000 (17:32 +0530)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 25 Mar 2025 19:21:45 +0000 (15:21 -0400)
This corrects the bootloader error codes for NXP chipsets.
Since we have a common handling for all error codes, there is no backward
compatibility issue.
Added error handling for CRC error code in V3 bootloader signature.

Fixes: 27489364299a ("Bluetooth: btnxpuart: Add handling for boot-signature timeout errors")
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
drivers/bluetooth/btnxpuart.c

index b440ba9292ec54786319795dc7f52299a4414668..b9d2fe5e992da9a67b02c39e91639154390895a4 100644 (file)
@@ -210,10 +210,11 @@ struct btnxpuart_dev {
 #define NXP_NAK_V3             0x7b
 #define NXP_CRC_ERROR_V3       0x7c
 
-/* Bootloader signature error codes */
-#define NXP_ACK_RX_TIMEOUT     0x0002  /* ACK not received from host */
-#define NXP_HDR_RX_TIMEOUT     0x0003  /* FW Header chunk not received */
-#define NXP_DATA_RX_TIMEOUT    0x0004  /* FW Data chunk not received */
+/* Bootloader signature error codes: Refer AN12820 from nxp.com */
+#define NXP_CRC_RX_ERROR       BIT(0)  /* CRC error in previous packet */
+#define NXP_ACK_RX_TIMEOUT     BIT(2)  /* ACK not received from host */
+#define NXP_HDR_RX_TIMEOUT     BIT(3)  /* FW Header chunk not received */
+#define NXP_DATA_RX_TIMEOUT    BIT(4)  /* FW Data chunk not received */
 
 #define HDR_LEN                        16
 
@@ -316,6 +317,16 @@ union nxp_v3_rx_timeout_nak_u {
        u8 buf[6];
 };
 
+struct nxp_v3_crc_nak {
+       u8 nak;
+       u8 crc;
+} __packed;
+
+union nxp_v3_crc_nak_u {
+       struct nxp_v3_crc_nak pkt;
+       u8 buf[2];
+};
+
 /* FW dump */
 #define NXP_FW_DUMP_SIZE       (1024 * 1000)
 
@@ -1089,25 +1100,27 @@ static void nxp_handle_fw_download_error(struct hci_dev *hdev, struct v3_data_re
        struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
        __u32 offset = __le32_to_cpu(req->offset);
        __u16 err = __le16_to_cpu(req->error);
-       union nxp_v3_rx_timeout_nak_u nak_tx_buf;
-
-       switch (err) {
-       case NXP_ACK_RX_TIMEOUT:
-       case NXP_HDR_RX_TIMEOUT:
-       case NXP_DATA_RX_TIMEOUT:
-               nak_tx_buf.pkt.nak = NXP_NAK_V3;
-               nak_tx_buf.pkt.offset = __cpu_to_le32(offset);
-               nak_tx_buf.pkt.crc = crc8(crc8_table, nak_tx_buf.buf,
-                                     sizeof(nak_tx_buf) - 1, 0xff);
-               serdev_device_write_buf(nxpdev->serdev, nak_tx_buf.buf,
-                                       sizeof(nak_tx_buf));
-               break;
-       default:
-               bt_dev_dbg(hdev, "Unknown bootloader error code: %d", err);
-               break;
-
+       union nxp_v3_rx_timeout_nak_u timeout_nak_buf;
+       union nxp_v3_crc_nak_u crc_nak_buf;
+
+       if (err & NXP_CRC_RX_ERROR) {
+               crc_nak_buf.pkt.nak = NXP_CRC_ERROR_V3;
+               crc_nak_buf.pkt.crc = crc8(crc8_table, crc_nak_buf.buf,
+                                          sizeof(crc_nak_buf) - 1, 0xff);
+               serdev_device_write_buf(nxpdev->serdev, crc_nak_buf.buf,
+                                       sizeof(crc_nak_buf));
+       } else if (err & NXP_ACK_RX_TIMEOUT ||
+                  err & NXP_HDR_RX_TIMEOUT ||
+                  err & NXP_DATA_RX_TIMEOUT) {
+               timeout_nak_buf.pkt.nak = NXP_NAK_V3;
+               timeout_nak_buf.pkt.offset = __cpu_to_le32(offset);
+               timeout_nak_buf.pkt.crc = crc8(crc8_table, timeout_nak_buf.buf,
+                                              sizeof(timeout_nak_buf) - 1, 0xff);
+               serdev_device_write_buf(nxpdev->serdev, timeout_nak_buf.buf,
+                                       sizeof(timeout_nak_buf));
+       } else {
+               bt_dev_err(hdev, "Unknown bootloader error code: %d", err);
        }
-
 }
 
 static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)