drivers/nfc/nxp-nci/firmware.c

Source file repositories/reference/linux-study-clean/drivers/nfc/nxp-nci/firmware.c

File Facts

System
Linux kernel
Corpus path
drivers/nfc/nxp-nci/firmware.c
Extension
.c
Size
7714 bytes
Lines
310
Domain
Driver Families
Bucket
drivers/nfc
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Generic driver for NXP NCI NFC chips
 *
 * Copyright (C) 2014  NXP Semiconductors  All rights reserved.
 *
 * Author: Clément Perrochaud <clement.perrochaud@nxp.com>
 *
 * Derived from PN544 device driver:
 * Copyright (C) 2012  Intel Corporation. All rights reserved.
 */

#include <linux/completion.h>
#include <linux/firmware.h>
#include <linux/nfc.h>
#include <linux/unaligned.h>

#include "nxp-nci.h"

/* Crypto operations can take up to 30 seconds */
#define NXP_NCI_FW_ANSWER_TIMEOUT	msecs_to_jiffies(30000)

#define NXP_NCI_FW_CMD_RESET		0xF0
#define NXP_NCI_FW_CMD_GETVERSION	0xF1
#define NXP_NCI_FW_CMD_CHECKINTEGRITY	0xE0
#define NXP_NCI_FW_CMD_WRITE		0xC0
#define NXP_NCI_FW_CMD_READ		0xA2
#define NXP_NCI_FW_CMD_GETSESSIONSTATE	0xF2
#define NXP_NCI_FW_CMD_LOG		0xA7
#define NXP_NCI_FW_CMD_FORCE		0xD0
#define NXP_NCI_FW_CMD_GET_DIE_ID	0xF4

#define NXP_NCI_FW_CHUNK_FLAG	0x0400

#define NXP_NCI_FW_RESULT_OK				0x00
#define NXP_NCI_FW_RESULT_INVALID_ADDR			0x01
#define NXP_NCI_FW_RESULT_GENERIC_ERROR			0x02
#define NXP_NCI_FW_RESULT_UNKNOWN_CMD			0x0B
#define NXP_NCI_FW_RESULT_ABORTED_CMD			0x0C
#define NXP_NCI_FW_RESULT_PLL_ERROR			0x0D
#define NXP_NCI_FW_RESULT_ADDR_RANGE_OFL_ERROR		0x1E
#define NXP_NCI_FW_RESULT_BUFFER_OFL_ERROR		0x1F
#define NXP_NCI_FW_RESULT_MEM_BSY			0x20
#define NXP_NCI_FW_RESULT_SIGNATURE_ERROR		0x21
#define NXP_NCI_FW_RESULT_FIRMWARE_VERSION_ERROR	0x24
#define NXP_NCI_FW_RESULT_PROTOCOL_ERROR		0x28
#define NXP_NCI_FW_RESULT_SFWU_DEGRADED			0x2A
#define NXP_NCI_FW_RESULT_PH_STATUS_FIRST_CHUNK		0x2D
#define NXP_NCI_FW_RESULT_PH_STATUS_NEXT_CHUNK		0x2E
#define NXP_NCI_FW_RESULT_PH_STATUS_INTERNAL_ERROR_5	0xC5

void nxp_nci_fw_work_complete(struct nxp_nci_info *info, int result)
{
	struct nxp_nci_fw_info *fw_info = &info->fw_info;
	int r;

	if (info->phy_ops->set_mode) {
		r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD);
		if (r < 0 && result == 0)
			result = -r;
	}

	info->mode = NXP_NCI_MODE_COLD;

	if (fw_info->fw) {
		release_firmware(fw_info->fw);
		fw_info->fw = NULL;
	}

	nfc_fw_download_done(info->ndev->nfc_dev, fw_info->name, (u32) -result);
}

/* crc_ccitt cannot be used since it is computed MSB first and not LSB first */
static u16 nxp_nci_fw_crc(u8 const *buffer, size_t len)
{
	u16 crc = 0xffff;

	while (len--) {
		crc = ((crc >> 8) | (crc << 8)) ^ *buffer++;
		crc ^= (crc & 0xff) >> 4;
		crc ^= (crc & 0xff) << 12;
		crc ^= (crc & 0xff) << 5;
	}

	return crc;
}

static int nxp_nci_fw_send_chunk(struct nxp_nci_info *info)
{
	struct nxp_nci_fw_info *fw_info = &info->fw_info;

Annotation

Implementation Notes