Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a680f2f3 authored by Wei Hu(Xavier)'s avatar Wei Hu(Xavier) Committed by Doug Ledford
Browse files

RDMA/hns: Add mailbox's implementation for hip08 RoCE driver



In hip08 SoC, the hardware implementation of mailbox command
has changed with hip06 SoC. As a result, it adjusts the
architecture of the command code and implements the interfaces
of mailbox for hip08 SoC.

Signed-off-by: default avatarLijun Ou <oulijun@huawei.com>
Signed-off-by: default avatarShaobo Xu <xushaobo2@huawei.com>
Signed-off-by: default avatarWei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent cfc85f3e
Loading
Loading
Loading
Loading
+6 −92
Original line number Diff line number Diff line
@@ -38,69 +38,7 @@

#define CMD_POLL_TOKEN		0xffff
#define CMD_MAX_NUM		32
#define STATUS_MASK		0xff
#define CMD_TOKEN_MASK		0x1f
#define GO_BIT_TIMEOUT_MSECS	10000

enum {
	HCR_TOKEN_OFFSET	= 0x14,
	HCR_STATUS_OFFSET	= 0x18,
	HCR_GO_BIT		= 15,
};

static int cmd_pending(struct hns_roce_dev *hr_dev)
{
	u32 status = readl(hr_dev->cmd.hcr + HCR_TOKEN_OFFSET);

	return (!!(status & (1 << HCR_GO_BIT)));
}

/* this function should be serialized with "hcr_mutex" */
static int __hns_roce_cmd_mbox_post_hw(struct hns_roce_dev *hr_dev,
				       u64 in_param, u64 out_param,
				       u32 in_modifier, u8 op_modifier, u16 op,
				       u16 token, int event)
{
	struct hns_roce_cmdq *cmd = &hr_dev->cmd;
	struct device *dev = &hr_dev->pdev->dev;
	u32 __iomem *hcr = (u32 *)cmd->hcr;
	int ret = -EAGAIN;
	unsigned long end;
	u32 val = 0;

	end = msecs_to_jiffies(GO_BIT_TIMEOUT_MSECS) + jiffies;
	while (cmd_pending(hr_dev)) {
		if (time_after(jiffies, end)) {
			dev_dbg(dev, "jiffies=%d end=%d\n", (int)jiffies,
				(int)end);
			goto out;
		}
		cond_resched();
	}

	roce_set_field(val, ROCEE_MB6_ROCEE_MB_CMD_M, ROCEE_MB6_ROCEE_MB_CMD_S,
		       op);
	roce_set_field(val, ROCEE_MB6_ROCEE_MB_CMD_MDF_M,
		       ROCEE_MB6_ROCEE_MB_CMD_MDF_S, op_modifier);
	roce_set_bit(val, ROCEE_MB6_ROCEE_MB_EVENT_S, event);
	roce_set_bit(val, ROCEE_MB6_ROCEE_MB_HW_RUN_S, 1);
	roce_set_field(val, ROCEE_MB6_ROCEE_MB_TOKEN_M,
		       ROCEE_MB6_ROCEE_MB_TOKEN_S, token);

	__raw_writeq(cpu_to_le64(in_param), hcr + 0);
	__raw_writeq(cpu_to_le64(out_param), hcr + 2);
	__raw_writel(cpu_to_le32(in_modifier), hcr + 4);
	/* Memory barrier */
	wmb();

	__raw_writel(cpu_to_le32(val), hcr + 5);

	mmiowb();
	ret = 0;

out:
	return ret;
}

static int hns_roce_cmd_mbox_post_hw(struct hns_roce_dev *hr_dev, u64 in_param,
				     u64 out_param, u32 in_modifier,
@@ -108,12 +46,11 @@ static int hns_roce_cmd_mbox_post_hw(struct hns_roce_dev *hr_dev, u64 in_param,
				     int event)
{
	struct hns_roce_cmdq *cmd = &hr_dev->cmd;
	int ret = -EAGAIN;
	int ret;

	mutex_lock(&cmd->hcr_mutex);
	ret = __hns_roce_cmd_mbox_post_hw(hr_dev, in_param, out_param,
					  in_modifier, op_modifier, op, token,
					  event);
	ret = hr_dev->hw->post_mbox(hr_dev, in_param, out_param, in_modifier,
				    op_modifier, op, token, event);
	mutex_unlock(&cmd->hcr_mutex);

	return ret;
@@ -126,9 +63,6 @@ static int __hns_roce_cmd_mbox_poll(struct hns_roce_dev *hr_dev, u64 in_param,
				    unsigned long timeout)
{
	struct device *dev = hr_dev->dev;
	u8 __iomem *hcr = hr_dev->cmd.hcr;
	unsigned long end = 0;
	u32 status = 0;
	int ret;

	ret = hns_roce_cmd_mbox_post_hw(hr_dev, in_param, out_param,
@@ -136,29 +70,10 @@ static int __hns_roce_cmd_mbox_poll(struct hns_roce_dev *hr_dev, u64 in_param,
					CMD_POLL_TOKEN, 0);
	if (ret) {
		dev_err(dev, "[cmd_poll]hns_roce_cmd_mbox_post_hw failed\n");
		goto out;
	}

	end = msecs_to_jiffies(timeout) + jiffies;
	while (cmd_pending(hr_dev) && time_before(jiffies, end))
		cond_resched();

	if (cmd_pending(hr_dev)) {
		dev_err(dev, "[cmd_poll]hw run cmd TIMEDOUT!\n");
		ret = -ETIMEDOUT;
		goto out;
	}

	status = le32_to_cpu((__force __be32)
			      __raw_readl(hcr + HCR_STATUS_OFFSET));
	if ((status & STATUS_MASK) != 0x1) {
		dev_err(dev, "mailbox status 0x%x!\n", status);
		ret = -EBUSY;
		goto out;
		return ret;
	}

out:
	return ret;
	return hr_dev->hw->chk_mbox(hr_dev, timeout);
}

static int hns_roce_cmd_mbox_poll(struct hns_roce_dev *hr_dev, u64 in_param,
@@ -198,7 +113,7 @@ static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param,
	struct hns_roce_cmdq *cmd = &hr_dev->cmd;
	struct hns_roce_cmd_context *context;
	struct device *dev = hr_dev->dev;
	int ret = 0;
	int ret;

	spin_lock(&cmd->context_lock);
	WARN_ON(cmd->free_head < 0);
@@ -280,7 +195,6 @@ int hns_roce_cmd_init(struct hns_roce_dev *hr_dev)
	hr_dev->cmd.use_events = 0;
	hr_dev->cmd.toggle = 1;
	hr_dev->cmd.max_cmds = CMD_MAX_NUM;
	hr_dev->cmd.hcr = hr_dev->reg_base + ROCEE_MB1_REG;
	hr_dev->cmd.pool = dma_pool_create("hns_roce_cmd", dev,
					   HNS_ROCE_MAILBOX_SIZE,
					   HNS_ROCE_MAILBOX_SIZE, 0);
+1 −0
Original line number Diff line number Diff line
@@ -341,6 +341,7 @@
#define ROCEE_BT_CMD_L_REG			0x200

#define ROCEE_MB1_REG				0x210
#define ROCEE_MB6_REG				0x224
#define ROCEE_DB_SQ_L_0_REG			0x230
#define ROCEE_DB_OTHERS_L_0_REG			0x238
#define ROCEE_QP1C_CFG0_0_REG			0x270
+4 −1
Original line number Diff line number Diff line
@@ -367,7 +367,6 @@ struct hns_roce_cmd_context {

struct hns_roce_cmdq {
	struct dma_pool		*pool;
	u8 __iomem		*hcr;
	struct mutex		hcr_mutex;
	struct semaphore	poll_sem;
	/*
@@ -517,6 +516,10 @@ struct hns_roce_hw {
	int (*hw_profile)(struct hns_roce_dev *hr_dev);
	int (*hw_init)(struct hns_roce_dev *hr_dev);
	void (*hw_exit)(struct hns_roce_dev *hr_dev);
	int (*post_mbox)(struct hns_roce_dev *hr_dev, u64 in_param,
			 u64 out_param, u32 in_modifier, u8 op_modifier, u16 op,
			 u16 token, int event);
	int (*chk_mbox)(struct hns_roce_dev *hr_dev, unsigned long timeout);
	void (*set_gid)(struct hns_roce_dev *hr_dev, u8 port, int gid_index,
			union ib_gid *gid);
	void (*set_mac)(struct hns_roce_dev *hr_dev, u8 phy_port, u8 *addr);
+75 −0
Original line number Diff line number Diff line
@@ -1619,6 +1619,79 @@ void hns_roce_v1_exit(struct hns_roce_dev *hr_dev)
	hns_roce_db_free(hr_dev);
}

static int hns_roce_v1_cmd_pending(struct hns_roce_dev *hr_dev)
{
	u32 status = readl(hr_dev->reg_base + ROCEE_MB6_REG);

	return (!!(status & (1 << HCR_GO_BIT)));
}

int hns_roce_v1_post_mbox(struct hns_roce_dev *hr_dev, u64 in_param,
			  u64 out_param, u32 in_modifier, u8 op_modifier,
			  u16 op, u16 token, int event)
{
	u32 *hcr = (u32 *)(hr_dev->reg_base + ROCEE_MB1_REG);
	unsigned long end;
	u32 val = 0;

	end = msecs_to_jiffies(GO_BIT_TIMEOUT_MSECS) + jiffies;
	while (hns_roce_v1_cmd_pending(hr_dev)) {
		if (time_after(jiffies, end)) {
			dev_err(hr_dev->dev, "jiffies=%d end=%d\n",
				(int)jiffies, (int)end);
			return -EAGAIN;
		}
		cond_resched();
	}

	roce_set_field(val, ROCEE_MB6_ROCEE_MB_CMD_M, ROCEE_MB6_ROCEE_MB_CMD_S,
		       op);
	roce_set_field(val, ROCEE_MB6_ROCEE_MB_CMD_MDF_M,
		       ROCEE_MB6_ROCEE_MB_CMD_MDF_S, op_modifier);
	roce_set_bit(val, ROCEE_MB6_ROCEE_MB_EVENT_S, event);
	roce_set_bit(val, ROCEE_MB6_ROCEE_MB_HW_RUN_S, 1);
	roce_set_field(val, ROCEE_MB6_ROCEE_MB_TOKEN_M,
		       ROCEE_MB6_ROCEE_MB_TOKEN_S, token);

	__raw_writeq(cpu_to_le64(in_param), hcr + 0);
	__raw_writeq(cpu_to_le64(out_param), hcr + 2);
	__raw_writel(cpu_to_le32(in_modifier), hcr + 4);
	/* Memory barrier */
	wmb();

	__raw_writel(cpu_to_le32(val), hcr + 5);

	mmiowb();

	return 0;
}

static int hns_roce_v1_chk_mbox(struct hns_roce_dev *hr_dev,
				unsigned long timeout)
{
	u8 __iomem *hcr = hr_dev->reg_base + ROCEE_MB1_REG;
	unsigned long end = 0;
	u32 status = 0;

	end = msecs_to_jiffies(timeout) + jiffies;
	while (hns_roce_v1_cmd_pending(hr_dev) && time_before(jiffies, end))
		cond_resched();

	if (hns_roce_v1_cmd_pending(hr_dev)) {
		dev_err(hr_dev->dev, "[cmd_poll]hw run cmd TIMEDOUT!\n");
		return -ETIMEDOUT;
	}

	status = le32_to_cpu((__force __be32)
			      __raw_readl(hcr + HCR_STATUS_OFFSET));
	if ((status & STATUS_MASK) != 0x1) {
		dev_err(hr_dev->dev, "mailbox status 0x%x!\n", status);
		return -EBUSY;
	}

	return 0;
}

void hns_roce_v1_set_gid(struct hns_roce_dev *hr_dev, u8 port, int gid_index,
			 union ib_gid *gid)
{
@@ -3849,6 +3922,8 @@ static const struct hns_roce_hw hns_roce_hw_v1 = {
	.hw_profile = hns_roce_v1_profile,
	.hw_init = hns_roce_v1_init,
	.hw_exit = hns_roce_v1_exit,
	.post_mbox = hns_roce_v1_post_mbox,
	.chk_mbox = hns_roce_v1_chk_mbox,
	.set_gid = hns_roce_v1_set_gid,
	.set_mac = hns_roce_v1_set_mac,
	.set_mtu = hns_roce_v1_set_mtu,
+5 −0
Original line number Diff line number Diff line
@@ -948,6 +948,11 @@ struct hns_roce_qp_context {
#define QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_M   \
	(((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_S)

#define STATUS_MASK		0xff
#define GO_BIT_TIMEOUT_MSECS	10000
#define HCR_STATUS_OFFSET	0x18
#define HCR_GO_BIT		15

struct hns_roce_rq_db {
	u32    u32_4;
	u32    u32_8;
Loading