drivers/crypto/intel/qat/qat_common/adf_admin.c

Source file repositories/reference/linux-study-clean/drivers/crypto/intel/qat/qat_common/adf_admin.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/intel/qat/qat_common/adf_admin.c
Extension
.c
Size
23153 bytes
Lines
720
Domain
Driver Families
Bucket
drivers/crypto
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

struct adf_admin_comms {
	dma_addr_t phy_addr;
	dma_addr_t const_tbl_addr;
	void *virt_addr;
	void *virt_tbl_addr;
	void __iomem *mailbox_addr;
	struct mutex lock;	/* protects adf_admin_comms struct */
};

static int adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev, u32 ae,
				  void *in, void *out)
{
	int ret;
	u32 status;
	struct adf_admin_comms *admin = accel_dev->admin;
	int offset = ae * ADF_ADMINMSG_LEN * 2;
	void __iomem *mailbox = admin->mailbox_addr;
	int mb_offset = ae * ADF_ADMIN_MAILBOX_STRIDE;
	struct icp_qat_fw_init_admin_req *request = in;

	mutex_lock(&admin->lock);

	if (ADF_CSR_RD(mailbox, mb_offset) == 1) {
		mutex_unlock(&admin->lock);
		return -EAGAIN;
	}

	memcpy(admin->virt_addr + offset, in, ADF_ADMINMSG_LEN);
	ADF_CSR_WR(mailbox, mb_offset, 1);

	ret = read_poll_timeout(ADF_CSR_RD, status, status == 0,
				ADF_ADMIN_POLL_DELAY_US,
				ADF_ADMIN_POLL_TIMEOUT_US, true,
				mailbox, mb_offset);
	if (ret < 0) {
		/* Response timeout */
		dev_err(&GET_DEV(accel_dev),
			"Failed to send admin msg %d to accelerator %d\n",
			request->cmd_id, ae);
	} else {
		/* Response received from admin message, we can now
		 * make response data available in "out" parameter.
		 */
		memcpy(out, admin->virt_addr + offset +
		       ADF_ADMINMSG_LEN, ADF_ADMINMSG_LEN);
	}

	mutex_unlock(&admin->lock);
	return ret;
}

static int adf_send_admin(struct adf_accel_dev *accel_dev,
			  struct icp_qat_fw_init_admin_req *req,
			  struct icp_qat_fw_init_admin_resp *resp,
			  const unsigned long ae_mask)
{
	u32 ae;

	for_each_set_bit(ae, &ae_mask, ICP_QAT_HW_AE_DELIMITER)
		if (adf_put_admin_msg_sync(accel_dev, ae, req, resp) ||
		    resp->status)
			return -EFAULT;

	return 0;
}

static int adf_init_ae(struct adf_accel_dev *accel_dev)
{
	struct icp_qat_fw_init_admin_req req;
	struct icp_qat_fw_init_admin_resp resp;
	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
	u32 ae_mask = hw_device->ae_mask;

	memset(&req, 0, sizeof(req));
	memset(&resp, 0, sizeof(resp));
	req.cmd_id = ICP_QAT_FW_INIT_AE;

	return adf_send_admin(accel_dev, &req, &resp, ae_mask);
}

static int adf_set_fw_constants(struct adf_accel_dev *accel_dev)
{
	struct icp_qat_fw_init_admin_req req;
	struct icp_qat_fw_init_admin_resp resp;
	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
	u32 ae_mask = hw_device->admin_ae_mask ?: hw_device->ae_mask;

	memset(&req, 0, sizeof(req));
	memset(&resp, 0, sizeof(resp));
	req.cmd_id = ICP_QAT_FW_CONSTANTS_CFG;

Annotation

Implementation Notes