提交 8207a83d 编写于 作者: W Weili Qian 提交者: Zheng Zengkai

crypto: hisilicon/qm - set the number of queues for function

mainline inclusion
from mainline-v5.13-rc1
commit 6250383a
category: feature
bugzilla: 173981
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6250383a2083e8f66635d441977f74e0ee4e52f7

----------------------------------------------------------------------

Kunpeng930 supports queue doorbell isolation.
When doorbell isolation is enabled, it supports to obtain the
maximum number of queues of one function from hardware register.
Otherwise, the 'max_qp_num' is the total number of queues.

When assigning queues to VF, it is necessary to ensure that the number
of VF queues does not exceed 'max_qp_num'.
Signed-off-by: NWeili Qian <qianweili@huawei.com>
Signed-off-by: NHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NMingqiang Ling <lingmingqiang@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 eecda517
...@@ -93,8 +93,11 @@ ...@@ -93,8 +93,11 @@
#define QM_DB_PRIORITY_SHIFT_V1 48 #define QM_DB_PRIORITY_SHIFT_V1 48
#define QM_DOORBELL_SQ_CQ_BASE_V2 0x1000 #define QM_DOORBELL_SQ_CQ_BASE_V2 0x1000
#define QM_DOORBELL_EQ_AEQ_BASE_V2 0x2000 #define QM_DOORBELL_EQ_AEQ_BASE_V2 0x2000
#define QM_QUE_ISO_CFG_V 0x0030
#define QM_QUE_ISO_EN 0x100154
#define QM_CAPBILITY 0x100158 #define QM_CAPBILITY 0x100158
#define QM_QP_NUN_MASK GENMASK(10, 0) #define QM_QP_NUN_MASK GENMASK(10, 0)
#define QM_QP_MAX_NUM_SHIFT 11
#define QM_DB_CMD_SHIFT_V2 12 #define QM_DB_CMD_SHIFT_V2 12
#define QM_DB_RAND_SHIFT_V2 16 #define QM_DB_RAND_SHIFT_V2 16
#define QM_DB_INDEX_SHIFT_V2 32 #define QM_DB_INDEX_SHIFT_V2 32
...@@ -876,6 +879,26 @@ static int qm_get_vft_v2(struct hisi_qm *qm, u32 *base, u32 *number) ...@@ -876,6 +879,26 @@ static int qm_get_vft_v2(struct hisi_qm *qm, u32 *base, u32 *number)
return 0; return 0;
} }
static int qm_get_vf_qp_num(struct hisi_qm *qm, u32 fun_num)
{
u32 remain_q_num, vfq_num;
u32 num_vfs = qm->vfs_num;
vfq_num = (qm->ctrl_qp_num - qm->qp_num) / num_vfs;
if (vfq_num >= qm->max_qp_num)
return qm->max_qp_num;
remain_q_num = (qm->ctrl_qp_num - qm->qp_num) % num_vfs;
if (vfq_num + remain_q_num <= qm->max_qp_num)
return fun_num == num_vfs ? vfq_num + remain_q_num : vfq_num;
/*
* if vfq_num + remain_q_num > max_qp_num, the last VFs,
* each with one more queue.
*/
return fun_num + remain_q_num > num_vfs ? vfq_num + 1 : vfq_num;
}
static struct hisi_qm *file_to_qm(struct debugfs_file *file) static struct hisi_qm *file_to_qm(struct debugfs_file *file)
{ {
struct qm_debug *debug = file->debug; struct qm_debug *debug = file->debug;
...@@ -939,25 +962,16 @@ static u32 current_qm_read(struct debugfs_file *file) ...@@ -939,25 +962,16 @@ static u32 current_qm_read(struct debugfs_file *file)
static int current_qm_write(struct debugfs_file *file, u32 val) static int current_qm_write(struct debugfs_file *file, u32 val)
{ {
struct hisi_qm *qm = file_to_qm(file); struct hisi_qm *qm = file_to_qm(file);
u32 vfq_num;
u32 tmp; u32 tmp;
if (val > qm->vfs_num) if (val > qm->vfs_num)
return -EINVAL; return -EINVAL;
/* According PF or VF Dev ID to calculation curr_qm_qp_num and store */ /* According PF or VF Dev ID to calculation curr_qm_qp_num and store */
if (!val) { if (!val)
qm->debug.curr_qm_qp_num = qm->qp_num; qm->debug.curr_qm_qp_num = qm->qp_num;
} else { else
vfq_num = (qm->ctrl_qp_num - qm->qp_num) / qm->vfs_num; qm->debug.curr_qm_qp_num = qm_get_vf_qp_num(qm, val);
if (val == qm->vfs_num)
qm->debug.curr_qm_qp_num =
qm->ctrl_qp_num - qm->qp_num -
(qm->vfs_num - 1) * vfq_num;
else
qm->debug.curr_qm_qp_num = vfq_num;
}
writel(val, qm->io_base + QM_DFX_MB_CNT_VF); writel(val, qm->io_base + QM_DFX_MB_CNT_VF);
writel(val, qm->io_base + QM_DFX_DB_CNT_VF); writel(val, qm->io_base + QM_DFX_DB_CNT_VF);
...@@ -3236,30 +3250,46 @@ EXPORT_SYMBOL_GPL(hisi_qm_alloc_qps_node); ...@@ -3236,30 +3250,46 @@ EXPORT_SYMBOL_GPL(hisi_qm_alloc_qps_node);
static int qm_vf_q_assign(struct hisi_qm *qm, u32 num_vfs) static int qm_vf_q_assign(struct hisi_qm *qm, u32 num_vfs)
{ {
u32 remain_q_num, q_num, i, j; u32 remain_q_num, vfs_q_num, act_q_num, q_num, i, j;
u32 max_qp_num = qm->max_qp_num;
u32 q_base = qm->qp_num; u32 q_base = qm->qp_num;
int ret; int ret;
if (!num_vfs) if (!num_vfs)
return -EINVAL; return -EINVAL;
remain_q_num = qm->ctrl_qp_num - qm->qp_num; vfs_q_num = qm->ctrl_qp_num - qm->qp_num;
/* If remain queues not enough, return error. */ /* If vfs_q_num is less than num_vfs, return error. */
if (qm->ctrl_qp_num < qm->qp_num || remain_q_num < num_vfs) if (vfs_q_num < num_vfs)
return -EINVAL; return -EINVAL;
q_num = remain_q_num / num_vfs; q_num = vfs_q_num / num_vfs;
for (i = 1; i <= num_vfs; i++) { remain_q_num = vfs_q_num % num_vfs;
if (i == num_vfs)
q_num += remain_q_num % num_vfs; for (i = num_vfs; i > 0; i--) {
ret = hisi_qm_set_vft(qm, i, q_base, q_num); /*
* if q_num + remain_q_num > max_qp_num in last vf, divide the
* remaining queues equally.
*/
if (i == num_vfs && q_num + remain_q_num <= max_qp_num) {
act_q_num = q_num + remain_q_num;
remain_q_num = 0;
} else if (remain_q_num > 0) {
act_q_num = q_num + 1;
remain_q_num--;
} else {
act_q_num = q_num;
}
act_q_num = min_t(int, act_q_num, max_qp_num);
ret = hisi_qm_set_vft(qm, i, q_base, act_q_num);
if (ret) { if (ret) {
for (j = i; j > 0; j--) for (j = num_vfs; j > i; j--)
hisi_qm_set_vft(qm, j, 0, 0); hisi_qm_set_vft(qm, j, 0, 0);
return ret; return ret;
} }
q_base += q_num; q_base += act_q_num;
} }
return 0; return 0;
...@@ -4180,7 +4210,7 @@ void hisi_qm_alg_unregister(struct hisi_qm *qm, struct hisi_qm_list *qm_list) ...@@ -4180,7 +4210,7 @@ void hisi_qm_alg_unregister(struct hisi_qm *qm, struct hisi_qm_list *qm_list)
} }
EXPORT_SYMBOL_GPL(hisi_qm_alg_unregister); EXPORT_SYMBOL_GPL(hisi_qm_alg_unregister);
static void qm_get_qp_num(struct hisi_qm *qm) static int qm_get_qp_num(struct hisi_qm *qm)
{ {
if (qm->ver == QM_HW_V1) if (qm->ver == QM_HW_V1)
qm->ctrl_qp_num = QM_QNUM_V1; qm->ctrl_qp_num = QM_QNUM_V1;
...@@ -4189,6 +4219,21 @@ static void qm_get_qp_num(struct hisi_qm *qm) ...@@ -4189,6 +4219,21 @@ static void qm_get_qp_num(struct hisi_qm *qm)
else else
qm->ctrl_qp_num = readl(qm->io_base + QM_CAPBILITY) & qm->ctrl_qp_num = readl(qm->io_base + QM_CAPBILITY) &
QM_QP_NUN_MASK; QM_QP_NUN_MASK;
if (qm->use_db_isolation)
qm->max_qp_num = (readl(qm->io_base + QM_CAPBILITY) >>
QM_QP_MAX_NUM_SHIFT) & QM_QP_NUN_MASK;
else
qm->max_qp_num = qm->ctrl_qp_num;
/* check if qp number is valid */
if (qm->qp_num > qm->max_qp_num) {
dev_err(&qm->pdev->dev, "qp num(%u) is more than max qp num(%u)!\n",
qm->qp_num, qm->max_qp_num);
return -EINVAL;
}
return 0;
} }
static int hisi_qm_pci_init(struct hisi_qm *qm) static int hisi_qm_pci_init(struct hisi_qm *qm)
...@@ -4218,8 +4263,11 @@ static int hisi_qm_pci_init(struct hisi_qm *qm) ...@@ -4218,8 +4263,11 @@ static int hisi_qm_pci_init(struct hisi_qm *qm)
goto err_release_mem_regions; goto err_release_mem_regions;
} }
if (qm->fun_type == QM_HW_PF) if (qm->fun_type == QM_HW_PF) {
qm_get_qp_num(qm); ret = qm_get_qp_num(qm);
if (ret)
goto err_iounmap;
}
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
if (ret < 0) if (ret < 0)
......
...@@ -207,6 +207,7 @@ struct hisi_qm { ...@@ -207,6 +207,7 @@ struct hisi_qm {
u32 qp_num; u32 qp_num;
u32 qp_in_used; u32 qp_in_used;
u32 ctrl_qp_num; u32 ctrl_qp_num;
u32 max_qp_num;
u32 vfs_num; u32 vfs_num;
struct list_head list; struct list_head list;
struct hisi_qm_list *qm_list; struct hisi_qm_list *qm_list;
...@@ -245,6 +246,9 @@ struct hisi_qm { ...@@ -245,6 +246,9 @@ struct hisi_qm {
const char *algs; const char *algs;
bool use_sva; bool use_sva;
bool is_frozen; bool is_frozen;
/* doorbell isolation enable */
bool use_db_isolation;
resource_size_t phys_base; resource_size_t phys_base;
resource_size_t phys_size; resource_size_t phys_size;
struct uacce_device *uacce; struct uacce_device *uacce;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册