Commit c59d8810 authored by Neeraj Sanjay Kale's avatar Neeraj Sanjay Kale Committed by Luiz Augusto von Dentz
Browse files

Bluetooth: btnxpuart: Add correct bootloader error codes



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: 27489364 ("Bluetooth: btnxpuart: Add handling for boot-signature timeout errors")
Signed-off-by: default avatarNeeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 3b5715ae
Loading
Loading
Loading
Loading
+35 −22
Original line number Diff line number Diff line
@@ -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)