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

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

File Facts

System
Linux kernel
Corpus path
drivers/crypto/intel/qat/qat_common/adf_telemetry.c
Extension
.c
Size
8213 bytes
Lines
328
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: implementation source
Status
source 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
/* Copyright (c) 2023 Intel Corporation. */
#define dev_fmt(fmt) "Telemetry: " fmt

#include <asm/errno.h>
#include <linux/atomic.h>
#include <linux/device.h>
#include <linux/dev_printk.h>
#include <linux/dma-mapping.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/workqueue.h>

#include "adf_admin.h"
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
#include "adf_telemetry.h"

#define TL_IS_ZERO(input)	((input) == 0)

static bool is_tl_supported(struct adf_accel_dev *accel_dev)
{
	u16 fw_caps =  GET_HW_DATA(accel_dev)->fw_capabilities;

	return fw_caps & TL_CAPABILITY_BIT;
}

static int validate_tl_data(struct adf_tl_hw_data *tl_data)
{
	if (!tl_data->dev_counters ||
	    TL_IS_ZERO(tl_data->num_dev_counters) ||
	    !tl_data->sl_util_counters ||
	    !tl_data->sl_exec_counters ||
	    !tl_data->rp_counters ||
	    TL_IS_ZERO(tl_data->num_rp_counters))
		return -EOPNOTSUPP;

	return 0;
}

static int validate_tl_slice_counters(struct icp_qat_fw_init_admin_slice_cnt *slice_count,
				      u8 max_slices_per_type)
{
	u8 *sl_counter = (u8 *)slice_count;
	int i;

	for (i = 0; i < ADF_TL_SL_CNT_COUNT; i++) {
		if (sl_counter[i] > max_slices_per_type)
			return -EINVAL;
	}

	return 0;
}

static int adf_tl_alloc_mem(struct adf_accel_dev *accel_dev)
{
	struct adf_tl_hw_data *tl_data = &GET_TL_DATA(accel_dev);
	struct device *dev = &GET_DEV(accel_dev);
	size_t regs_sz = tl_data->layout_sz;
	struct adf_telemetry *telemetry;
	int node = dev_to_node(dev);
	void *tl_data_regs;
	unsigned int i;

	telemetry = kzalloc_node(sizeof(*telemetry), GFP_KERNEL, node);
	if (!telemetry)
		return -ENOMEM;

	telemetry->rp_num_indexes = kmalloc_array(tl_data->max_rp,
						  sizeof(*telemetry->rp_num_indexes),
						  GFP_KERNEL);
	if (!telemetry->rp_num_indexes)
		goto err_free_tl;

	telemetry->regs_hist_buff = kmalloc_objs(*telemetry->regs_hist_buff,
						 tl_data->num_hbuff);
	if (!telemetry->regs_hist_buff)
		goto err_free_rp_indexes;

	telemetry->regs_data = dma_alloc_coherent(dev, regs_sz,
						  &telemetry->regs_data_p,
						  GFP_KERNEL);
	if (!telemetry->regs_data)
		goto err_free_regs_hist_buff;

	for (i = 0; i < tl_data->num_hbuff; i++) {
		tl_data_regs = kzalloc_node(regs_sz, GFP_KERNEL, node);

Annotation

Implementation Notes