Skip to content

Commit 3bbf078

Browse files
yekai123123herbertx
authored andcommitted
crypto: hisilicon/qm - supports to inquiry each function's QoS
1. The ACC driver supports to inquiry each function's QoS in the Host and VM. The driver supports reading QoS by the device debug SysFS attribute file "alg_qos", like "cat alg_qos". 2. Modify the communication process between pf and vf as needed. Signed-off-by: Kai Ye <yekai13@huawei.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent 2966d9d commit 3bbf078

1 file changed

Lines changed: 174 additions & 7 deletions

File tree

  • drivers/crypto/hisilicon

drivers/crypto/hisilicon/qm.c

Lines changed: 174 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#define QM_MB_CMD_DATA_ADDR_L 0x304
5252
#define QM_MB_CMD_DATA_ADDR_H 0x308
5353
#define QM_MB_PING_ALL_VFS 0xffff
54+
#define QM_MB_CMD_DATA_SHIFT 32
5455
#define QM_MB_CMD_DATA_MASK GENMASK(31, 0)
5556

5657
/* sqc shift */
@@ -185,6 +186,7 @@
185186

186187
/* interfunction communication */
187188
#define QM_IFC_READY_STATUS 0x100128
189+
#define QM_IFC_C_STS_M 0x10012C
188190
#define QM_IFC_INT_SET_P 0x100130
189191
#define QM_IFC_INT_CFG 0x100134
190192
#define QM_IFC_INT_SOURCE_P 0x100138
@@ -256,6 +258,7 @@
256258
#define QM_SHAPER_CBS_B 1
257259
#define QM_SHAPER_CBS_S 16
258260
#define QM_SHAPER_VFT_OFFSET 6
261+
#define WAIT_FOR_QOS_VF 100
259262
#define QM_QOS_MIN_ERROR_RATE 5
260263
#define QM_QOS_TYPICAL_NUM 8
261264
#define QM_SHAPER_MIN_CBS_S 8
@@ -328,6 +331,8 @@ enum qm_mb_cmd {
328331
QM_VF_PREPARE_FAIL,
329332
QM_VF_START_DONE,
330333
QM_VF_START_FAIL,
334+
QM_PF_SET_QOS,
335+
QM_VF_GET_QOS,
331336
};
332337

333338
struct qm_cqe {
@@ -2124,7 +2129,7 @@ static void qm_trigger_vf_interrupt(struct hisi_qm *qm, u32 fun_num)
21242129
u32 val;
21252130

21262131
val = readl(qm->io_base + QM_IFC_INT_CFG);
2127-
val |= ~QM_IFC_SEND_ALL_VFS;
2132+
val &= ~QM_IFC_SEND_ALL_VFS;
21282133
val |= fun_num;
21292134
writel(val, qm->io_base + QM_IFC_INT_CFG);
21302135

@@ -3926,6 +3931,139 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos)
39263931
return 0;
39273932
}
39283933

3934+
static u32 qm_get_shaper_vft_qos(struct hisi_qm *qm, u32 fun_index)
3935+
{
3936+
u64 cir_u = 0, cir_b = 0, cir_s = 0;
3937+
u64 shaper_vft, ir_calc, ir;
3938+
unsigned int val;
3939+
u32 error_rate;
3940+
int ret;
3941+
3942+
ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val,
3943+
val & BIT(0), POLL_PERIOD,
3944+
POLL_TIMEOUT);
3945+
if (ret)
3946+
return 0;
3947+
3948+
writel(0x1, qm->io_base + QM_VFT_CFG_OP_WR);
3949+
writel(SHAPER_VFT, qm->io_base + QM_VFT_CFG_TYPE);
3950+
writel(fun_index, qm->io_base + QM_VFT_CFG);
3951+
3952+
writel(0x0, qm->io_base + QM_VFT_CFG_RDY);
3953+
writel(0x1, qm->io_base + QM_VFT_CFG_OP_ENABLE);
3954+
3955+
ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val,
3956+
val & BIT(0), POLL_PERIOD,
3957+
POLL_TIMEOUT);
3958+
if (ret)
3959+
return 0;
3960+
3961+
shaper_vft = readl(qm->io_base + QM_VFT_CFG_DATA_L) |
3962+
((u64)readl(qm->io_base + QM_VFT_CFG_DATA_H) << 32);
3963+
3964+
cir_b = shaper_vft & QM_SHAPER_CIR_B_MASK;
3965+
cir_u = shaper_vft & QM_SHAPER_CIR_U_MASK;
3966+
cir_u = cir_u >> QM_SHAPER_FACTOR_CIR_U_SHIFT;
3967+
3968+
cir_s = shaper_vft & QM_SHAPER_CIR_S_MASK;
3969+
cir_s = cir_s >> QM_SHAPER_FACTOR_CIR_S_SHIFT;
3970+
3971+
ir_calc = acc_shaper_para_calc(cir_b, cir_u, cir_s);
3972+
3973+
ir = qm->factor[fun_index].func_qos * QM_QOS_RATE;
3974+
3975+
error_rate = QM_QOS_EXPAND_RATE * (u32)abs(ir_calc - ir) / ir;
3976+
if (error_rate > QM_QOS_MIN_ERROR_RATE) {
3977+
pci_err(qm->pdev, "error_rate: %u, get function qos is error!\n", error_rate);
3978+
return 0;
3979+
}
3980+
3981+
return ir;
3982+
}
3983+
3984+
static void qm_vf_get_qos(struct hisi_qm *qm, u32 fun_num)
3985+
{
3986+
struct device *dev = &qm->pdev->dev;
3987+
u64 mb_cmd;
3988+
u32 qos;
3989+
int ret;
3990+
3991+
qos = qm_get_shaper_vft_qos(qm, fun_num);
3992+
if (!qos) {
3993+
dev_err(dev, "function(%u) failed to get qos by PF!\n", fun_num);
3994+
return;
3995+
}
3996+
3997+
mb_cmd = QM_PF_SET_QOS | (u64)qos << QM_MB_CMD_DATA_SHIFT;
3998+
ret = qm_ping_single_vf(qm, mb_cmd, fun_num);
3999+
if (ret)
4000+
dev_err(dev, "failed to send cmd to VF(%u)!\n", fun_num);
4001+
}
4002+
4003+
static int qm_vf_read_qos(struct hisi_qm *qm)
4004+
{
4005+
int cnt = 0;
4006+
int ret;
4007+
4008+
/* reset mailbox qos val */
4009+
qm->mb_qos = 0;
4010+
4011+
/* vf ping pf to get function qos */
4012+
if (qm->ops->ping_pf) {
4013+
ret = qm->ops->ping_pf(qm, QM_VF_GET_QOS);
4014+
if (ret) {
4015+
pci_err(qm->pdev, "failed to send cmd to PF to get qos!\n");
4016+
return ret;
4017+
}
4018+
}
4019+
4020+
while (true) {
4021+
msleep(QM_WAIT_DST_ACK);
4022+
if (qm->mb_qos)
4023+
break;
4024+
4025+
if (++cnt > QM_MAX_VF_WAIT_COUNT) {
4026+
pci_err(qm->pdev, "PF ping VF timeout!\n");
4027+
return -ETIMEDOUT;
4028+
}
4029+
}
4030+
4031+
return ret;
4032+
}
4033+
4034+
static ssize_t qm_algqos_read(struct file *filp, char __user *buf,
4035+
size_t count, loff_t *pos)
4036+
{
4037+
struct hisi_qm *qm = filp->private_data;
4038+
char tbuf[QM_DBG_READ_LEN];
4039+
u32 qos_val, ir;
4040+
int ret;
4041+
4042+
/* Mailbox and reset cannot be operated at the same time */
4043+
if (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) {
4044+
pci_err(qm->pdev, "dev resetting, read alg qos failed!\n");
4045+
return -EAGAIN;
4046+
}
4047+
4048+
if (qm->fun_type == QM_HW_PF) {
4049+
ir = qm_get_shaper_vft_qos(qm, 0);
4050+
} else {
4051+
ret = qm_vf_read_qos(qm);
4052+
if (ret)
4053+
goto err_get_status;
4054+
ir = qm->mb_qos;
4055+
}
4056+
4057+
qos_val = ir / QM_QOS_RATE;
4058+
ret = scnprintf(tbuf, QM_DBG_READ_LEN, "%u\n", qos_val);
4059+
4060+
ret = simple_read_from_buffer(buf, count, pos, tbuf, ret);
4061+
4062+
err_get_status:
4063+
clear_bit(QM_RESETTING, &qm->misc_ctl);
4064+
return ret;
4065+
}
4066+
39294067
static ssize_t qm_qos_value_init(const char *buf, unsigned long *val)
39304068
{
39314069
int buflen = strlen(buf);
@@ -4020,6 +4158,7 @@ static ssize_t qm_algqos_write(struct file *filp, const char __user *buf,
40204158
static const struct file_operations qm_algqos_fops = {
40214159
.owner = THIS_MODULE,
40224160
.open = simple_open,
4161+
.read = qm_algqos_read,
40234162
.write = qm_algqos_write,
40244163
};
40254164

@@ -5129,10 +5268,8 @@ static void qm_pf_reset_vf_process(struct hisi_qm *qm,
51295268
qm_reset_bit_clear(qm);
51305269
}
51315270

5132-
static void qm_cmd_process(struct work_struct *cmd_process)
5271+
static void qm_handle_cmd_msg(struct hisi_qm *qm, u32 fun_num)
51335272
{
5134-
struct hisi_qm *qm = container_of(cmd_process,
5135-
struct hisi_qm, cmd_process);
51365273
struct device *dev = &qm->pdev->dev;
51375274
u64 msg;
51385275
u32 cmd;
@@ -5142,8 +5279,8 @@ static void qm_cmd_process(struct work_struct *cmd_process)
51425279
* Get the msg from source by sending mailbox. Whether message is got
51435280
* successfully, destination needs to ack source by clearing the interrupt.
51445281
*/
5145-
ret = qm_get_mb_cmd(qm, &msg, 0);
5146-
qm_clear_cmd_interrupt(qm, 0);
5282+
ret = qm_get_mb_cmd(qm, &msg, fun_num);
5283+
qm_clear_cmd_interrupt(qm, BIT(fun_num));
51475284
if (ret) {
51485285
dev_err(dev, "failed to get msg from source!\n");
51495286
return;
@@ -5157,12 +5294,42 @@ static void qm_cmd_process(struct work_struct *cmd_process)
51575294
case QM_PF_SRST_PREPARE:
51585295
qm_pf_reset_vf_process(qm, QM_SOFT_RESET);
51595296
break;
5297+
case QM_VF_GET_QOS:
5298+
qm_vf_get_qos(qm, fun_num);
5299+
break;
5300+
case QM_PF_SET_QOS:
5301+
qm->mb_qos = msg >> QM_MB_CMD_DATA_SHIFT;
5302+
break;
51605303
default:
5161-
dev_err(dev, "unsupported cmd %u sent by PF!\n", cmd);
5304+
dev_err(dev, "unsupported cmd %u sent by function(%u)!\n", cmd, fun_num);
51625305
break;
51635306
}
51645307
}
51655308

5309+
static void qm_cmd_process(struct work_struct *cmd_process)
5310+
{
5311+
struct hisi_qm *qm = container_of(cmd_process,
5312+
struct hisi_qm, cmd_process);
5313+
u32 vfs_num = qm->vfs_num;
5314+
u64 val;
5315+
u32 i;
5316+
5317+
if (qm->fun_type == QM_HW_PF) {
5318+
val = readq(qm->io_base + QM_IFC_INT_SOURCE_P);
5319+
if (!val)
5320+
return;
5321+
5322+
for (i = 1; i <= vfs_num; i++) {
5323+
if (val & BIT(i))
5324+
qm_handle_cmd_msg(qm, i);
5325+
}
5326+
5327+
return;
5328+
}
5329+
5330+
qm_handle_cmd_msg(qm, 0);
5331+
}
5332+
51665333
/**
51675334
* hisi_qm_alg_register() - Register alg to crypto and add qm to qm_list.
51685335
* @qm: The qm needs add.

0 commit comments

Comments
 (0)