--- /dev/null
+What: /sys/bus/pci/devices/<BDF>/qat_kpt/
+Date: August 2026
+KernelVersion: 7.2
+Contact: qat-linux@intel.com
+Description:
+ Directory containing attributes related to the QAT Key Protection
+ Technology (KPT) feature. KPT allows cryptographic keys to be used
+ by the accelerator without being exposed in plaintext to the host.
+
+What: /sys/bus/pci/devices/<BDF>/qat_kpt/enable
+Date: August 2026
+KernelVersion: 7.2
+Contact: qat-linux@intel.com
+Description:
+ (RW) Enables or disables Key Protection Technology (KPT).
+
+ Write 1 to enable KPT, or 0 to disable it.
+
+ Example usage::
+
+ # cat /sys/bus/pci/devices/<BDF>/qat_kpt/enable
+ 0
+ # echo 1 > /sys/bus/pci/devices/<BDF>/qat_kpt/enable
+
+ This attribute is only available on devices that support KPT.
+
+What: /sys/bus/pci/devices/<BDF>/qat_kpt/swk_cnt_per_fn
+Date: August 2026
+KernelVersion: 7.2
+Contact: qat-linux@intel.com
+Description:
+ (RW) Configures the maximum number of KPT symmetric wrapping keys
+ (SWKs) that a Virtual Function (VF) may be associated with.
+
+ Valid values range from 0 to 128. A value of 0 indicates no limit.
+
+ Example usage::
+
+ # cat /sys/bus/pci/devices/<BDF>/qat_kpt/swk_cnt_per_fn
+ 128
+ # echo 128 > /sys/bus/pci/devices/<BDF>/qat_kpt/swk_cnt_per_fn
+
+ This attribute is only available on devices that support KPT.
+
+What: /sys/bus/pci/devices/<BDF>/qat_kpt/swk_cnt_per_pasid
+Date: August 2026
+KernelVersion: 7.2
+Contact: qat-linux@intel.com
+Description:
+ (RW) Configures the maximum number of KPT symmetric wrapping keys
+ (SWKs) per Process Address Space ID (PASID).
+
+ Valid values range from 0 to 128. A value of 0 indicates no limit.
+
+ Example usage::
+
+ # cat /sys/bus/pci/devices/<BDF>/qat_kpt/swk_cnt_per_pasid
+ 128
+ # echo 128 > /sys/bus/pci/devices/<BDF>/qat_kpt/swk_cnt_per_pasid
+
+ This attribute is only available on devices that support KPT.
+
+What: /sys/bus/pci/devices/<BDF>/qat_kpt/swk_max_ttl
+Date: August 2026
+KernelVersion: 7.2
+Contact: qat-linux@intel.com
+Description:
+ (RW) Configures the maximum Time To Live (TTL) for KPT symmetric
+ wrapping keys (SWK).
+
+ Valid values range from 0 to 31536000 seconds. A value of 0
+ indicates that the SWK TTL is unlimited.
+
+ Example usage::
+
+ # cat /sys/bus/pci/devices/<BDF>/qat_kpt/swk_max_ttl
+ 1000
+ # echo 1000 > /sys/bus/pci/devices/<BDF>/qat_kpt/swk_max_ttl
+
+ This attribute is only available on devices that support KPT.
+
+What: /sys/bus/pci/devices/<BDF>/qat_kpt/swk_shared
+Date: August 2026
+KernelVersion: 7.2
+Contact: qat-linux@intel.com
+Description:
+ (RW) Controls shared mode for KPT symmetric wrapping keys (SWK).
+
+ Write 1 to enable shared mode, or 0 to disable it (non-shared mode).
+
+ Example usage::
+
+ # cat /sys/bus/pci/devices/<BDF>/qat_kpt/swk_shared
+ 0
+ # echo 1 > /sys/bus/pci/devices/<BDF>/qat_kpt/swk_shared
+
+ This attribute is only available on devices that support KPT.
unsigned long mask;
u32 caps = 0;
u32 fusectl1;
+ u32 fusectl0;
if (adf_6xxx_is_wcy(GET_HW_DATA(accel_dev)))
return get_accel_cap_wcy(accel_dev);
+ fusectl0 = GET_HW_DATA(accel_dev)->fuses[ADF_FUSECTL0];
fusectl1 = GET_HW_DATA(accel_dev)->fuses[ADF_FUSECTL1];
/* Read accelerator capabilities mask */
capabilities_asym = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |
ICP_ACCEL_CAPABILITIES_SM2 |
- ICP_ACCEL_CAPABILITIES_ECEDMONT;
+ ICP_ACCEL_CAPABILITIES_ECEDMONT |
+ ICP_ACCEL_CAPABILITIES_KPT;
if (fusectl1 & ICP_ACCEL_GEN6_MASK_PKE_SLICE) {
capabilities_asym &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
capabilities_asym &= ~ICP_ACCEL_CAPABILITIES_ECEDMONT;
}
+ if (fusectl0 & ADF_GEN6_KPT_FUSE_BIT)
+ capabilities_asym &= ~ICP_ACCEL_CAPABILITIES_KPT;
+
capabilities_dc = ICP_ACCEL_CAPABILITIES_COMPRESSION |
ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION |
ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION |
return ret;
}
+static void adf_gen6_init_kpt(struct adf_kpt_hw_data *kpt_data)
+{
+ kpt_data->max_swk_cnt_per_fn_pasid = ADF_6XXX_KPT_MAX_SWK_COUNT_PER_FNPASID;
+ kpt_data->max_swk_ttl = ADF_6XXX_KPT_MAX_SWK_TTL;
+
+ kpt_data->user_input.enable = false;
+ kpt_data->user_input.swk_shared = ADF_6XXX_KPT_DEFAULT_SWK_SHARED_MODE;
+ kpt_data->user_input.swk_max_ttl = ADF_6XXX_KPT_DEFAULT_SWK_TTL;
+ kpt_data->user_input.swk_cnt_per_fn = ADF_6XXX_KPT_DEFAULT_SWK_CNT_PER_FN;
+ kpt_data->user_input.swk_cnt_per_pasid = ADF_6XXX_KPT_DEFAULT_SWK_CNT_PER_PASID;
+}
+
static void adf_gen6_init_rl_data(struct adf_rl_hw_data *rl_data)
{
rl_data->pciout_tb_offset = ADF_GEN6_RL_TOKEN_PCIEOUT_BUCKET_OFFSET;
adf_gen6_init_tl_data(&hw_data->tl_data);
adf_gen6_init_rl_data(&hw_data->rl_data);
adf_gen6_init_anti_rb(&hw_data->anti_rb_data);
+ adf_gen6_init_kpt(&hw_data->kpt_data);
}
void adf_clean_hw_data_6xxx(struct adf_hw_device_data *hw_data)
/* Fuse bits */
#define ADF_GEN6_ANTI_RB_FUSE_BIT BIT(24)
+#define ADF_GEN6_KPT_FUSE_BIT BIT(16)
/*
* Watchdog timers
/* Clock frequency */
#define ADF_6XXX_AE_FREQ (1000 * HZ_PER_MHZ)
+/* KPT */
+#define ADF_6XXX_KPT_MAX_SWK_COUNT_PER_FNPASID 128
+#define ADF_6XXX_KPT_MAX_SWK_TTL 31536000
+#define ADF_6XXX_KPT_DEFAULT_SWK_SHARED_MODE 1
+#define ADF_6XXX_KPT_DEFAULT_SWK_TTL 0
+#define ADF_6XXX_KPT_DEFAULT_SWK_CNT_PER_FN 0
+#define ADF_6XXX_KPT_DEFAULT_SWK_CNT_PER_PASID 0
+
enum icp_qat_gen6_slice_mask {
ICP_ACCEL_GEN6_MASK_UCS_SLICE = BIT(0),
ICP_ACCEL_GEN6_MASK_AUTH_SLICE = BIT(1),
#include <adf_cfg.h>
#include <adf_common_drv.h>
#include <adf_dbgfs.h>
+#include <adf_sysfs_kpt.h>
#include "adf_gen6_shared.h"
#include "adf_6xxx_hw_data.h"
return ret;
ret = adf_sysfs_init(accel_dev);
+ if (ret)
+ return ret;
+
+ if (!(hw_data->fuses[ADF_FUSECTL0] & ADF_GEN6_KPT_FUSE_BIT))
+ ret = adf_sysfs_init_kpt(accel_dev);
return ret;
}
adf_hw_arbiter.o \
adf_init.o \
adf_isr.o \
+ adf_kpt.o \
adf_module.o \
adf_mstate_mgr.o \
adf_rl_admin.o \
adf_rl.o \
adf_sysfs.o \
adf_sysfs_anti_rb.o \
+ adf_sysfs_kpt.o \
adf_sysfs_ras_counters.o \
adf_sysfs_rl.o \
adf_timer.o \
#include "adf_anti_rb.h"
#include "adf_cfg_common.h"
#include "adf_dc.h"
+#include "adf_kpt.h"
#include "adf_rl.h"
#include "adf_telemetry.h"
#include "adf_pfvf_msg.h"
struct adf_rl_hw_data rl_data;
struct adf_tl_hw_data tl_data;
struct adf_anti_rb_hw_data anti_rb_data;
+ struct adf_kpt_hw_data kpt_data;
struct qat_migdev_ops vfmig_ops;
const char *fw_name;
const char *fw_mmp_name;
#include "adf_common_drv.h"
#include "adf_cfg.h"
#include "adf_heartbeat.h"
+#include "adf_kpt.h"
#include "icp_qat_fw_init_admin.h"
#define ADF_ADMIN_MAILBOX_STRIDE 0x1000
return adf_send_admin_svn(accel_dev, ICP_QAT_FW_SVN_COMMIT, &resp);
}
+static_assert(sizeof(struct icp_qat_fw_init_admin_kpt_cfg) < PAGE_SIZE);
+
+static void adf_cfg_kpt_config(struct adf_accel_dev *accel_dev,
+ struct icp_qat_fw_init_admin_kpt_cfg *kpt_config)
+{
+ struct adf_kpt_interface_data *user_data = GET_KPT_USER_DATA(accel_dev);
+
+ kpt_config->swk_cnt_per_fn = user_data->swk_cnt_per_fn;
+ kpt_config->swk_cnt_per_pasid = user_data->swk_cnt_per_pasid;
+ kpt_config->swk_ttl_in_secs = user_data->swk_max_ttl;
+ kpt_config->swk_shared_disable = !user_data->swk_shared;
+}
+
+int adf_send_admin_kpt_init(struct adf_accel_dev *accel_dev, void *init_cfg,
+ size_t init_cfg_sz, dma_addr_t init_ptr)
+{
+ struct icp_qat_fw_init_admin_kpt_cfg *kpt_config = init_cfg;
+ u32 ae_mask = GET_HW_DATA(accel_dev)->admin_ae_mask;
+ struct icp_qat_fw_init_admin_resp resp = { };
+ struct icp_qat_fw_init_admin_req req = { };
+ int ret;
+
+ if (!kpt_config || init_cfg_sz < sizeof(*kpt_config))
+ return -EINVAL;
+
+ adf_cfg_kpt_config(accel_dev, kpt_config);
+
+ req.cmd_id = ICP_QAT_FW_KPT_ENABLE;
+ req.init_cfg_ptr = init_ptr;
+ req.init_cfg_sz = sizeof(*kpt_config);
+
+ ret = adf_send_admin(accel_dev, &req, &resp, ae_mask);
+ if (ret)
+ dev_err(&GET_DEV(accel_dev), "Failed to send KPT init admin message\n");
+
+ return ret;
+}
+
int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
{
struct adf_admin_comms *admin;
int adf_send_admin_tl_stop(struct adf_accel_dev *accel_dev);
int adf_send_admin_arb_query(struct adf_accel_dev *accel_dev, int cmd, u8 *svn);
int adf_send_admin_arb_commit(struct adf_accel_dev *accel_dev);
+int adf_send_admin_kpt_init(struct adf_accel_dev *accel_dev, void *init_cfg,
+ size_t init_cfg_sz, dma_addr_t init_ptr);
#endif
#include "adf_dbgfs.h"
#include "adf_heartbeat.h"
#include "adf_rl.h"
+#include "adf_kpt.h"
#include "adf_sysfs_anti_rb.h"
#include "adf_sysfs_ras_counters.h"
#include "adf_telemetry.h"
return -EFAULT;
}
+ /* Enable Key Protection Technology (KPT) */
+ ret = adf_enable_kpt(accel_dev);
+ if (ret) {
+ dev_err(&GET_DEV(accel_dev), "Failed to enable KPT\n");
+ return ret;
+ }
+
if (hw_data->start_timer) {
ret = hw_data->start_timer(accel_dev);
if (ret) {
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2026 Intel Corporation */
+#include <linux/dma-mapping.h>
+
+#include "adf_admin.h"
+#include "adf_cfg_services.h"
+#include "adf_common_drv.h"
+#include "adf_kpt.h"
+
+static bool adf_kpt_supported(struct adf_accel_dev *accel_dev)
+{
+ struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
+
+ return hw_data->accel_capabilities_mask & ICP_ACCEL_CAPABILITIES_KPT;
+}
+
+int adf_enable_kpt(struct adf_accel_dev *accel_dev)
+{
+ struct adf_kpt_interface_data *user_data = GET_KPT_USER_DATA(accel_dev);
+ struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
+ dma_addr_t paddr;
+ void *vaddr;
+ int ret;
+ int svc;
+
+ /* Return 0 if KPT is not supported by the hardware */
+ if (!adf_kpt_supported(accel_dev))
+ return 0;
+
+ if (!user_data->enable) {
+ /* Disable KPT capability if user has not enabled it */
+ hw_data->accel_capabilities_mask &= ~ICP_ACCEL_CAPABILITIES_KPT;
+ return 0;
+ }
+
+ svc = adf_get_service_enabled(accel_dev);
+ if (svc < 0)
+ return svc;
+
+ if (svc != SVC_ASYM) {
+ dev_err(&GET_DEV(accel_dev),
+ "KPT can only be enabled when service is configured as 'asym'\n");
+ return -EINVAL;
+ }
+
+ vaddr = dma_alloc_coherent(&GET_DEV(accel_dev), PAGE_SIZE, &paddr,
+ GFP_KERNEL);
+ if (!vaddr)
+ return -ENOMEM;
+
+ ret = adf_send_admin_kpt_init(accel_dev, vaddr, PAGE_SIZE, paddr);
+
+ dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE, vaddr, paddr);
+
+ return ret;
+}
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright(c) 2026 Intel Corporation */
+#ifndef ADF_KPT_H_
+#define ADF_KPT_H_
+
+#include <linux/types.h>
+
+#define GET_KPT_CFG_DATA(accel_dev) (&(accel_dev)->hw_device->kpt_data)
+#define GET_KPT_USER_DATA(accel_dev) (&(accel_dev)->hw_device->kpt_data.user_input)
+
+struct adf_accel_dev;
+
+struct adf_kpt_interface_data {
+ bool enable;
+ bool swk_shared;
+ unsigned int swk_cnt_per_fn;
+ unsigned int swk_cnt_per_pasid;
+ unsigned int swk_max_ttl;
+};
+
+struct adf_kpt_hw_data {
+ unsigned int max_swk_cnt_per_fn_pasid;
+ unsigned int max_swk_ttl;
+ struct adf_kpt_interface_data user_input;
+};
+
+int adf_enable_kpt(struct adf_accel_dev *accel_dev);
+
+#endif /* ADF_KPT_H_ */
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2026 Intel Corporation */
+#include <linux/sysfs.h>
+#include <linux/types.h>
+
+#include "adf_cfg.h"
+#include "adf_cfg_services.h"
+#include "adf_common_drv.h"
+#include "adf_kpt.h"
+#include "adf_sysfs_kpt.h"
+
+static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct adf_kpt_interface_data *user_data;
+ struct adf_accel_dev *accel_dev;
+
+ accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+ if (!accel_dev)
+ return -EINVAL;
+
+ user_data = GET_KPT_USER_DATA(accel_dev);
+
+ return sysfs_emit(buf, "%d\n", user_data->enable);
+}
+
+static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct adf_kpt_interface_data *user_data;
+ struct adf_hw_device_data *hw_data;
+ struct adf_accel_dev *accel_dev;
+ bool enable;
+ int ret;
+
+ accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+ if (!accel_dev)
+ return -EINVAL;
+
+ if (adf_dev_started(accel_dev)) {
+ dev_info(dev, "Device qat_dev%d must be down before enabling KPT\n",
+ accel_dev->accel_id);
+ return -EINVAL;
+ }
+
+ if (adf_get_service_enabled(accel_dev) != SVC_ASYM) {
+ dev_info(dev, "KPT can only be enabled when the asymmetric service is enabled\n");
+ return -EINVAL;
+ }
+
+ hw_data = GET_HW_DATA(accel_dev);
+
+ /*
+ * Restore the KPT capability bit in the device's capabilities mask
+ * before processing user input, as the bit may have been cleared if
+ * KPT was previously disabled by the user.
+ */
+ hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev);
+ if (!hw_data->accel_capabilities_mask)
+ return -EINVAL;
+
+ ret = kstrtobool(buf, &enable);
+ if (ret)
+ return ret;
+
+ user_data = GET_KPT_USER_DATA(accel_dev);
+ user_data->enable = enable;
+
+ return count;
+}
+static DEVICE_ATTR_RW(enable);
+
+static ssize_t swk_shared_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct adf_kpt_interface_data *user_data;
+ struct adf_accel_dev *accel_dev;
+
+ accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+ if (!accel_dev)
+ return -EINVAL;
+
+ user_data = GET_KPT_USER_DATA(accel_dev);
+
+ return sysfs_emit(buf, "%d\n", user_data->swk_shared);
+}
+
+static ssize_t swk_shared_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct adf_kpt_interface_data *user_data;
+ struct adf_accel_dev *accel_dev;
+ bool swk_shared;
+ int ret;
+
+ accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+ if (!accel_dev)
+ return -EINVAL;
+
+ if (adf_dev_started(accel_dev)) {
+ dev_info(dev, "Device qat_dev%d must be down before setting swk_shared\n",
+ accel_dev->accel_id);
+ return -EINVAL;
+ }
+
+ ret = kstrtobool(buf, &swk_shared);
+ if (ret)
+ return ret;
+
+ user_data = GET_KPT_USER_DATA(accel_dev);
+ user_data->swk_shared = swk_shared;
+
+ return count;
+}
+static DEVICE_ATTR_RW(swk_shared);
+
+static ssize_t swk_max_ttl_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct adf_kpt_interface_data *user_data;
+ struct adf_accel_dev *accel_dev;
+
+ accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+ if (!accel_dev)
+ return -EINVAL;
+
+ user_data = GET_KPT_USER_DATA(accel_dev);
+
+ return sysfs_emit(buf, "%u\n", user_data->swk_max_ttl);
+}
+
+static ssize_t swk_max_ttl_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct adf_kpt_hw_data *kpt_data;
+ struct adf_accel_dev *accel_dev;
+ unsigned int swk_max_ttl;
+ int ret;
+
+ accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+ if (!accel_dev)
+ return -EINVAL;
+
+ if (adf_dev_started(accel_dev)) {
+ dev_info(dev, "Device qat_dev%d must be down before setting swk_max_ttl\n",
+ accel_dev->accel_id);
+ return -EINVAL;
+ }
+
+ ret = kstrtouint(buf, 10, &swk_max_ttl);
+ if (ret)
+ return ret;
+
+ kpt_data = GET_KPT_CFG_DATA(accel_dev);
+
+ if (swk_max_ttl > kpt_data->max_swk_ttl) {
+ dev_info(dev, "Configuration value is out of range (%u - %u)\n",
+ 0, kpt_data->max_swk_ttl);
+ return -EINVAL;
+ }
+
+ kpt_data->user_input.swk_max_ttl = swk_max_ttl;
+
+ return count;
+}
+static DEVICE_ATTR_RW(swk_max_ttl);
+
+static ssize_t swk_cnt_per_fn_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct adf_kpt_interface_data *user_data;
+ struct adf_accel_dev *accel_dev;
+
+ accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+ if (!accel_dev)
+ return -EINVAL;
+
+ user_data = GET_KPT_USER_DATA(accel_dev);
+
+ return sysfs_emit(buf, "%u\n", user_data->swk_cnt_per_fn);
+}
+
+static ssize_t swk_cnt_per_fn_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct adf_kpt_hw_data *kpt_data;
+ struct adf_accel_dev *accel_dev;
+ unsigned int swk_cnt_per_fn;
+ int ret;
+
+ accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+ if (!accel_dev)
+ return -EINVAL;
+
+ if (adf_dev_started(accel_dev)) {
+ dev_info(dev, "Device qat_dev%d must be down before setting swk_cnt_per_fn\n",
+ accel_dev->accel_id);
+ return -EINVAL;
+ }
+
+ ret = kstrtouint(buf, 10, &swk_cnt_per_fn);
+ if (ret)
+ return ret;
+
+ kpt_data = GET_KPT_CFG_DATA(accel_dev);
+
+ if (swk_cnt_per_fn > kpt_data->max_swk_cnt_per_fn_pasid) {
+ dev_info(dev, "swk_cnt_per_fn: value out of range (0 - %u)\n",
+ kpt_data->max_swk_cnt_per_fn_pasid);
+ return -EINVAL;
+ }
+
+ kpt_data->user_input.swk_cnt_per_fn = swk_cnt_per_fn;
+
+ return count;
+}
+static DEVICE_ATTR_RW(swk_cnt_per_fn);
+
+static ssize_t swk_cnt_per_pasid_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct adf_kpt_interface_data *user_data;
+ struct adf_accel_dev *accel_dev;
+
+ accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+ if (!accel_dev)
+ return -EINVAL;
+
+ user_data = GET_KPT_USER_DATA(accel_dev);
+
+ return sysfs_emit(buf, "%u\n", user_data->swk_cnt_per_pasid);
+}
+
+static ssize_t swk_cnt_per_pasid_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct adf_kpt_hw_data *kpt_data;
+ struct adf_accel_dev *accel_dev;
+ unsigned int swk_cnt_per_pasid;
+ int ret;
+
+ accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+ if (!accel_dev)
+ return -EINVAL;
+
+ if (adf_dev_started(accel_dev)) {
+ dev_info(dev, "Device qat_dev%d must be down before setting swk_cnt_per_pasid\n",
+ accel_dev->accel_id);
+ return -EINVAL;
+ }
+
+ ret = kstrtouint(buf, 10, &swk_cnt_per_pasid);
+ if (ret)
+ return ret;
+
+ kpt_data = GET_KPT_CFG_DATA(accel_dev);
+
+ if (swk_cnt_per_pasid > kpt_data->max_swk_cnt_per_fn_pasid) {
+ dev_info(dev, "swk_cnt_per_pasid: value out of range (0 - %u)\n",
+ kpt_data->max_swk_cnt_per_fn_pasid);
+ return -EINVAL;
+ }
+
+ kpt_data->user_input.swk_cnt_per_pasid = swk_cnt_per_pasid;
+
+ return count;
+}
+static DEVICE_ATTR_RW(swk_cnt_per_pasid);
+
+static struct attribute *qat_kpt_attrs[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_swk_shared.attr,
+ &dev_attr_swk_max_ttl.attr,
+ &dev_attr_swk_cnt_per_fn.attr,
+ &dev_attr_swk_cnt_per_pasid.attr,
+ NULL,
+};
+
+static const struct attribute_group qat_kpt_group = {
+ .attrs = qat_kpt_attrs,
+ .name = "qat_kpt",
+};
+
+int adf_sysfs_init_kpt(struct adf_accel_dev *accel_dev)
+{
+ int ret;
+
+ ret = devm_device_add_group(&GET_DEV(accel_dev), &qat_kpt_group);
+ if (ret) {
+ dev_err(&GET_DEV(accel_dev), "Failed to create qat_kpt attribute group\n");
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_sysfs_init_kpt);
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright(c) 2026 Intel Corporation */
+#ifndef ADF_SYSFS_KPT_H_
+#define ADF_SYSFS_KPT_H_
+
+struct adf_accel_dev;
+
+int adf_sysfs_init_kpt(struct adf_accel_dev *accel_dev);
+
+#endif /* ADF_SYSFS_KPT_H_ */
ICP_QAT_FW_RL_REMOVE = 136,
ICP_QAT_FW_TL_START = 137,
ICP_QAT_FW_TL_STOP = 138,
+ ICP_QAT_FW_KPT_ENABLE = 144,
ICP_QAT_FW_SVN_READ = 146,
ICP_QAT_FW_SVN_COMMIT = 147,
};
__u32 resvrd3[6];
};
+struct icp_qat_fw_init_admin_kpt_cfg {
+ __u32 swk_cnt_per_fn;
+ __u32 swk_cnt_per_pasid;
+ __u32 swk_ttl_in_secs;
+ __u32 swk_shared_disable;
+};
+
#endif
ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION = BIT(24),
ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION = BIT(25),
ICP_ACCEL_CAPABILITIES_AES_V2 = BIT(26),
- /* Bits 27-28 are currently reserved */
+ ICP_ACCEL_CAPABILITIES_KPT = BIT(27),
+ /* Bit 28 is currently reserved */
ICP_ACCEL_CAPABILITIES_ZUC_256 = BIT(29),
ICP_ACCEL_CAPABILITIES_WIRELESS_CRYPTO_EXT = BIT(30),
};