Commit 203ec155 authored by Yu Zhang's avatar Yu Zhang Committed by JiangShui
Browse files

hns3 udma: support modify jfr function

driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I85R2F


CVE: NA

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

The modify_jfr function is used to modify the threshold of the remaining
WQEs in the JFR. When the number of remaining WQEs is less than the
threshold, the UDMA hardware triggers the JFR_LIMIT_REACH asynchronous
event.

Signed-off-by: default avatarYu Zhang <zhangyu709@huawei.com>
parent 5f85590f
Loading
Loading
Loading
Loading
+61 −0
Original line number Original line Diff line number Diff line
@@ -442,6 +442,67 @@ int udma_destroy_jfr(struct ubcore_jfr *jfr)
	return 0;
	return 0;
}
}


static int udma_hw_modify_srq(struct udma_dev *dev, uint32_t jfrn,
			      uint16_t jfr_limit)
{
	struct udma_jfr_context *jfr_context;
	struct udma_jfr_context *jfrc_mask;
	struct udma_cmd_mailbox *mailbox;
	struct udma_cmq_desc desc;
	struct udma_mbox *mb;
	int ret;

	mailbox = udma_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);
	jfr_context = (struct udma_jfr_context *)mailbox->buf;
	jfrc_mask = (struct udma_jfr_context *)mailbox->buf + 1;
	memset(jfrc_mask, 0xff, sizeof(*jfrc_mask));
	udma_reg_write(jfr_context, SRQC_LIMIT_WL, jfr_limit);
	udma_reg_clear(jfrc_mask, SRQC_LIMIT_WL);

	mb = (struct udma_mbox *)desc.data;
	udma_cmq_setup_basic_desc(&desc, UDMA_OPC_POST_MB, false);
	mbox_desc_init(mb, mailbox->dma, 0, jfrn, UDMA_CMD_MODIFY_SRQC);

	ret = udma_cmd_mbox(dev, &desc, UDMA_CMD_TIMEOUT_MSECS, 0);
	if (ret)
		dev_err(dev->dev, "modify JFR(%u) cmd error(%d).\n",
			jfrn, ret);
	udma_free_cmd_mailbox(dev, mailbox);

	return ret;
}

int udma_modify_jfr(struct ubcore_jfr *jfr, const struct ubcore_jfr_attr *attr,
		    struct ubcore_udata *udata)
{
	struct udma_dev *udma_dev = to_udma_dev(jfr->ub_dev);
	struct udma_jfr *udma_jfr = to_udma_jfr(jfr);
	uint32_t jfr_limit;
	int ret;

	if (!(attr->mask & UBCORE_JFR_RX_THRESHOLD)) {
		dev_err(udma_dev->dev, "JFR threshold mask is not set.\n");
		return -EINVAL;
	}

	jfr_limit = attr->rx_threshold;
	if (jfr_limit > udma_jfr->wqe_cnt) {
		dev_err(udma_dev->dev,
			"JFR limit(%u) larger than wqe num(%u).\n",
			jfr_limit, udma_jfr->wqe_cnt);
		return -EINVAL;
	}

	ret = udma_hw_modify_srq(udma_dev, udma_jfr->jfrn, jfr_limit);
	if (ret)
		dev_err(udma_dev->dev,
			"hw modify srq failed, ret = %d.\n", ret);

	return ret;
}

void udma_jfr_event(struct udma_dev *udma_dev, uint32_t jfrn, int event_type)
void udma_jfr_event(struct udma_dev *udma_dev, uint32_t jfrn, int event_type)
{
{
	struct udma_jfr_table *jfr_table = &udma_dev->jfr_table;
	struct udma_jfr_table *jfr_table = &udma_dev->jfr_table;
+2 −0
Original line number Original line Diff line number Diff line
@@ -87,6 +87,8 @@ static inline struct udma_jfr *to_udma_jfr(struct ubcore_jfr *ubcore_jfr)
struct ubcore_jfr *udma_create_jfr(struct ubcore_device *dev, const struct ubcore_jfr_cfg *cfg,
struct ubcore_jfr *udma_create_jfr(struct ubcore_device *dev, const struct ubcore_jfr_cfg *cfg,
			      struct ubcore_udata *udata);
			      struct ubcore_udata *udata);
int udma_destroy_jfr(struct ubcore_jfr *jfr);
int udma_destroy_jfr(struct ubcore_jfr *jfr);
int udma_modify_jfr(struct ubcore_jfr *jfr, const struct ubcore_jfr_attr *attr,
		    struct ubcore_udata *udata);
void udma_jfr_event(struct udma_dev *udma_dev, uint32_t jfrn, int event_type);
void udma_jfr_event(struct udma_dev *udma_dev, uint32_t jfrn, int event_type);


#endif /* _UDMA_JFR_H */
#endif /* _UDMA_JFR_H */
+1 −0
Original line number Original line Diff line number Diff line
@@ -204,6 +204,7 @@ static struct ubcore_ops g_udma_dev_ops = {
	.modify_jfc = udma_modify_jfc,
	.modify_jfc = udma_modify_jfc,
	.destroy_jfc = udma_destroy_jfc,
	.destroy_jfc = udma_destroy_jfc,
	.create_jfr = udma_create_jfr,
	.create_jfr = udma_create_jfr,
	.modify_jfr = udma_modify_jfr,
	.destroy_jfr = udma_destroy_jfr,
	.destroy_jfr = udma_destroy_jfr,
};
};