Available for PF and VF in host. VF in guest currently only
has one debug register.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/dev_usage
+Date: Mar 2026
+Contact: linux-crypto@vger.kernel.org
+Description: Query the real-time bandwidth usage of device.
+ Returns the bandwidth usage of each channel on the device.
+ The returned number is in percentage.
+
What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/current_q
Date: Sep 2019
Contact: linux-crypto@vger.kernel.org
1/1000~1000/1000 of total QoS. The driver reading alg_qos to
get related QoS in the host and VM, Such as "cat alg_qos".
+What: /sys/kernel/debug/hisi_sec2/<bdf>/dev_usage
+Date: Mar 2026
+Contact: linux-crypto@vger.kernel.org
+Description: Query the real-time bandwidth usage of device.
+ Returns the bandwidth usage of each channel on the device.
+ The returned number is in percentage.
+
What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/qm_regs
Date: Oct 2019
Contact: linux-crypto@vger.kernel.org
1/1000~1000/1000 of total QoS. The driver reading alg_qos to
get related QoS in the host and VM, Such as "cat alg_qos".
+What: /sys/kernel/debug/hisi_zip/<bdf>/dev_usage
+Date: Mar 2026
+Contact: linux-crypto@vger.kernel.org
+Description: Query the real-time bandwidth usage of device.
+ Returns the bandwidth usage of each channel on the device.
+ The returned number is in percentage.
+
What: /sys/kernel/debug/hisi_zip/<bdf>/qm/regs
Date: Nov 2018
Contact: linux-crypto@vger.kernel.org
}
}
+static int qm_usage_percent(struct hisi_qm *qm, int chan_num)
+{
+ u32 val, used_bw, total_bw;
+
+ val = readl(qm->io_base + QM_CHANNEL_USAGE_OFFSET +
+ chan_num * QM_CHANNEL_ADDR_INTRVL);
+ used_bw = lower_16_bits(val);
+ total_bw = upper_16_bits(val);
+ if (!total_bw)
+ return -EIO;
+
+ if (total_bw <= used_bw)
+ return QM_MAX_DEV_USAGE;
+
+ return (used_bw * QM_DEV_USAGE_RATE) / total_bw;
+}
+
+static int qm_usage_show(struct seq_file *s, void *unused)
+{
+ struct hisi_qm *qm = s->private;
+ bool dev_is_active = true;
+ int i, ret;
+
+ /* If device is in suspended, usage is 0. */
+ ret = hisi_qm_get_dfx_access(qm);
+ if (ret == -EAGAIN) {
+ dev_is_active = false;
+ } else if (ret) {
+ dev_err(&qm->pdev->dev, "failed to get dfx access for usage_show!\n");
+ return ret;
+ }
+
+ ret = 0;
+ for (i = 0; i < qm->channel_data.channel_num; i++) {
+ if (dev_is_active) {
+ ret = qm_usage_percent(qm, i);
+ if (ret < 0) {
+ hisi_qm_put_dfx_access(qm);
+ return ret;
+ }
+ }
+ seq_printf(s, "%s: %d\n", qm->channel_data.channel_name[i], ret);
+ }
+
+ if (dev_is_active)
+ hisi_qm_put_dfx_access(qm);
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(qm_usage);
+
static int qm_diff_regs_show(struct seq_file *s, void *unused)
{
struct hisi_qm *qm = s->private;
debugfs_create_file("diff_regs", 0444, qm->debug.qm_d,
qm, &qm_diff_regs_fops);
+ if (qm->ver >= QM_HW_V5)
+ debugfs_create_file("dev_usage", 0444, qm->debug.debug_root, qm, &qm_usage_fops);
+
debugfs_create_file("regs", 0444, qm->debug.qm_d, qm, &qm_regs_fops);
debugfs_create_file("cmd", 0600, qm->debug.qm_d, qm, &qm_cmd_fops);
#define HPRE_DFX_COMMON2_LEN 0xE
#define HPRE_DFX_CORE_LEN 0x43
+#define HPRE_MAX_CHANNEL_NUM 2
+
static const char hpre_name[] = "hisi_hpre";
static struct dentry *hpre_debugfs_root;
static const struct pci_device_id hpre_dev_ids[] = {
},
};
+static const char *hpre_channel_name[HPRE_MAX_CHANNEL_NUM] = {
+ "RSA",
+ "ECC",
+};
+
static const struct hisi_qm_err_ini hpre_err_ini;
bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg)
return 0;
}
+static void hpre_set_channels(struct hisi_qm *qm)
+{
+ struct qm_channel *channel_data = &qm->channel_data;
+ int i;
+
+ channel_data->channel_num = HPRE_MAX_CHANNEL_NUM;
+ for (i = 0; i < HPRE_MAX_CHANNEL_NUM; i++)
+ channel_data->channel_name[i] = hpre_channel_name[i];
+}
+
static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
u64 alg_msk;
return ret;
}
+ hpre_set_channels(qm);
/* Fetch and save the value of capability registers */
ret = hpre_pre_store_cap_reg(qm);
if (ret) {
#define SEC_AEAD_BITMAP (GENMASK_ULL(7, 6) | GENMASK_ULL(18, 17) | \
GENMASK_ULL(45, 43))
+#define SEC_MAX_CHANNEL_NUM 1
+
struct sec_hw_error {
u32 int_msk;
const char *msg;
return 0;
}
+static void sec_set_channels(struct hisi_qm *qm)
+{
+ struct qm_channel *channel_data = &qm->channel_data;
+
+ channel_data->channel_num = SEC_MAX_CHANNEL_NUM;
+ channel_data->channel_name[0] = "SEC";
+}
+
static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
u64 alg_msk;
return ret;
}
+ sec_set_channels(qm);
/* Fetch and save the value of capability registers */
ret = sec_pre_store_cap_reg(qm);
if (ret) {
#define HZIP_LIT_LEN_EN_OFFSET 0x301204
#define HZIP_LIT_LEN_EN_EN BIT(4)
+#define HZIP_MAX_CHANNEL_NUM 3
+
enum {
HZIP_HIGH_COMP_RATE,
HZIP_HIGH_COMP_PERF,
},
};
+static const char *zip_channel_name[HZIP_MAX_CHANNEL_NUM] = {
+ "COMPRESS",
+ "DECOMPRESS",
+ "DAE"
+};
+
static int hzip_diff_regs_show(struct seq_file *s, void *unused)
{
struct hisi_qm *qm = s->private;
return 0;
}
+static void zip_set_channels(struct hisi_qm *qm)
+{
+ struct qm_channel *channel_data = &qm->channel_data;
+ int i;
+
+ channel_data->channel_num = HZIP_MAX_CHANNEL_NUM;
+ for (i = 0; i < HZIP_MAX_CHANNEL_NUM; i++)
+ channel_data->channel_name[i] = zip_channel_name[i];
+}
+
static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
u64 alg_msk;
return ret;
}
+ zip_set_channels(qm);
/* Fetch and save the value of capability registers */
ret = zip_pre_store_cap_reg(qm);
if (ret) {
#define QM_MIG_REGION_SEL 0x100198
#define QM_MIG_REGION_EN BIT(0)
+#define QM_MAX_CHANNEL_NUM 8
+#define QM_CHANNEL_USAGE_OFFSET 0x1100
+#define QM_MAX_DEV_USAGE 100
+#define QM_DEV_USAGE_RATE 100
+#define QM_CHANNEL_ADDR_INTRVL 0x4
+
/* uacce mode of the driver */
#define UACCE_MODE_NOUACCE 0 /* don't use uacce */
#define UACCE_MODE_SVA 1 /* use uacce sva mode */
struct qm_dma qcdma;
};
+struct qm_channel {
+ int channel_num;
+ const char *channel_name[QM_MAX_CHANNEL_NUM];
+};
+
struct hisi_qm {
enum qm_hw_ver ver;
enum qm_fun_type fun_type;
struct qm_err_isolate isolate_data;
struct hisi_qm_cap_tables cap_tables;
+ struct qm_channel channel_data;
};
struct hisi_qp_status {