Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1685811

[PATCH net 04/20] net/hinic: Initialize api cmd hw

From Aviad Krawczyk <aviad.krawczyk@huawei.com>
Newsgroups linux.kernel
Subject [PATCH net 04/20] net/hinic: Initialize api cmd hw
Date 2017-07-12 16:30 +0200
Message-ID <u2qOm-VU-3@gated-at.bofh.it> (permalink)
References <u2qEF-Q6-9@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


Update the hardware about api cmd resources and initialize api cmd hw.

Signed-off-by: Aviad Krawczyk <aviad.krawczyk@huawei.com>
Sigend-off-by: Zhaochen <zhaochen6@huawei.com>
---
 .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.c   | 174 ++++++++++++++++++++-
 .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.h   |  38 +++++
 drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h   |  25 +++
 3 files changed, 236 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
index dc80fa7..1cd91ae 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
@@ -15,6 +15,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/pci.h>
@@ -22,8 +23,12 @@
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/bitops.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/log2.h>
 #include <asm/byteorder.h>
 
+#include "hinic_hw_csr.h"
 #include "hinic_hw_if.h"
 #include "hinic_hw_api_cmd.h"
 
@@ -36,8 +41,157 @@
 		(((cell_size) >= API_CMD_CELL_SIZE_MIN) ? \
 		 (1 << (fls(cell_size - 1))) : API_CMD_CELL_SIZE_MIN)
 
+#define API_CMD_CELL_SIZE_VAL(size)		\
+		ilog2((size) >> API_CMD_CELL_SIZE_SHIFT)
+
 #define API_CMD_BUF_SIZE			2048
 
+#define API_CMD_TIMEOUT			1000
+
+enum api_cmd_xor_chk_level {
+	XOR_CHK_DIS = 0,
+
+	XOR_CHK_ALL = 3,
+};
+
+/**
+ * api_cmd_hw_restart - restart the chain in the HW
+ * @chain: the API CMD specific chain to restart
+ *
+ * Return 0 - Success, negative - Failure
+ **/
+static int api_cmd_hw_restart(struct hinic_api_cmd_chain *chain)
+{
+	struct hinic_hwif *hwif = chain->hwif;
+	unsigned long end;
+	u32 reg_addr, val;
+	int err = -ETIMEDOUT;
+
+	/* Read Modify Write */
+	reg_addr = HINIC_CSR_API_CMD_CHAIN_REQ_ADDR(chain->chain_type);
+	val = hinic_hwif_read_reg(hwif, reg_addr);
+
+	val = HINIC_API_CMD_CHAIN_REQ_CLEAR(val, RESTART);
+	val |= HINIC_API_CMD_CHAIN_REQ_SET(1, RESTART);
+
+	hinic_hwif_write_reg(hwif, reg_addr, val);
+
+	end = jiffies + msecs_to_jiffies(API_CMD_TIMEOUT);
+	do {
+		val = hinic_hwif_read_reg(hwif, reg_addr);
+
+		if (!HINIC_API_CMD_CHAIN_REQ_GET(val, RESTART)) {
+			err = 0;
+			break;
+		}
+
+		msleep(20);
+	} while (time_before(jiffies, end));
+
+	return err;
+}
+
+/**
+ * api_cmd_ctrl_init - set the control register of a chain
+ * @chain: the API CMD specific chain to set control register for
+ **/
+static void api_cmd_ctrl_init(struct hinic_api_cmd_chain *chain)
+{
+	struct hinic_hwif *hwif = chain->hwif;
+	u32 reg_addr, ctrl;
+	u16 cell_size;
+
+	/* Read Modify Write */
+	reg_addr = HINIC_CSR_API_CMD_CHAIN_CTRL_ADDR(chain->chain_type);
+
+	cell_size = API_CMD_CELL_SIZE_VAL(chain->cell_size);
+
+	ctrl = hinic_hwif_read_reg(hwif, reg_addr);
+
+	ctrl =  HINIC_API_CMD_CHAIN_CTRL_CLEAR(ctrl, RESTART_WB_STAT) &
+		HINIC_API_CMD_CHAIN_CTRL_CLEAR(ctrl, XOR_ERR)	&
+		HINIC_API_CMD_CHAIN_CTRL_CLEAR(ctrl, AEQE_EN)	&
+		HINIC_API_CMD_CHAIN_CTRL_CLEAR(ctrl, XOR_CHK_EN) &
+		HINIC_API_CMD_CHAIN_CTRL_CLEAR(ctrl, CELL_SIZE);
+
+	ctrl |= HINIC_API_CMD_CHAIN_CTRL_SET(1, XOR_ERR) |
+		HINIC_API_CMD_CHAIN_CTRL_SET(XOR_CHK_ALL, XOR_CHK_EN) |
+		HINIC_API_CMD_CHAIN_CTRL_SET(cell_size, CELL_SIZE);
+
+	hinic_hwif_write_reg(hwif, reg_addr, ctrl);
+}
+
+/**
+ * api_cmd_set_status_addr - set the status address of a chain in the HW
+ * @chain: the API CMD specific chain to set in HW status address for
+ **/
+static void api_cmd_set_status_addr(struct hinic_api_cmd_chain *chain)
+{
+	struct hinic_hwif *hwif = chain->hwif;
+	u32 addr, val;
+
+	addr = HINIC_CSR_API_CMD_STATUS_HI_ADDR(chain->chain_type);
+	val = upper_32_bits(chain->wb_status_paddr);
+	hinic_hwif_write_reg(hwif, addr, val);
+
+	addr = HINIC_CSR_API_CMD_STATUS_LO_ADDR(chain->chain_type);
+	val = lower_32_bits(chain->wb_status_paddr);
+	hinic_hwif_write_reg(hwif, addr, val);
+}
+
+/**
+ * api_cmd_set_num_cells - set the number cells of a chain in the HW
+ * @chain: the API CMD specific chain to set in HW the number of cells for
+ **/
+static void api_cmd_set_num_cells(struct hinic_api_cmd_chain *chain)
+{
+	struct hinic_hwif *hwif = chain->hwif;
+	u32 addr, val;
+
+	addr = HINIC_CSR_API_CMD_CHAIN_NUM_CELLS_ADDR(chain->chain_type);
+	val  = chain->num_cells;
+	hinic_hwif_write_reg(hwif, addr, val);
+}
+
+/**
+ * api_cmd_head_init - set the head of a chain in the HW
+ * @chain: the API CMD specific chain to set in HW the head for
+ **/
+static void api_cmd_head_init(struct hinic_api_cmd_chain *chain)
+{
+	struct hinic_hwif *hwif = chain->hwif;
+	u32 addr, val;
+
+	addr = HINIC_CSR_API_CMD_CHAIN_HEAD_HI_ADDR(chain->chain_type);
+	val = upper_32_bits(chain->head_cell_paddr);
+	hinic_hwif_write_reg(hwif, addr, val);
+
+	addr = HINIC_CSR_API_CMD_CHAIN_HEAD_LO_ADDR(chain->chain_type);
+	val = lower_32_bits(chain->head_cell_paddr);
+	hinic_hwif_write_reg(hwif, addr, val);
+}
+
+/**
+ * api_cmd_chain_hw_clean - clean the HW
+ * @chain: the API CMD specific chain
+ **/
+static void api_cmd_chain_hw_clean(struct hinic_api_cmd_chain *chain)
+{
+	struct hinic_hwif *hwif = chain->hwif;
+	u32 addr, ctrl;
+
+	addr = HINIC_CSR_API_CMD_CHAIN_CTRL_ADDR(chain->chain_type);
+
+	ctrl = hinic_hwif_read_reg(hwif, addr);
+	ctrl = HINIC_API_CMD_CHAIN_CTRL_CLEAR(ctrl, RESTART_WB_STAT) &
+		HINIC_API_CMD_CHAIN_CTRL_CLEAR(ctrl, XOR_ERR)	&
+		HINIC_API_CMD_CHAIN_CTRL_CLEAR(ctrl, AEQE_EN)	&
+		HINIC_API_CMD_CHAIN_CTRL_CLEAR(ctrl, XOR_CHK_EN) &
+		HINIC_API_CMD_CHAIN_CTRL_CLEAR(ctrl, CELL_SIZE);
+
+	hinic_hwif_write_reg(hwif, addr, ctrl);
+}
+
 /**
  * api_cmd_chain_hw_init - initialize the chain in the HW
  * @chain: the API CMD specific chain to initialize in HW
@@ -46,7 +200,24 @@
  **/
 static int api_cmd_chain_hw_init(struct hinic_api_cmd_chain *chain)
 {
-	/* should be implemented */
+	struct hinic_hwif *hwif = chain->hwif;
+	struct pci_dev *pdev = hwif->pdev;
+	int err;
+
+	api_cmd_chain_hw_clean(chain);
+
+	api_cmd_set_status_addr(chain);
+
+	err = api_cmd_hw_restart(chain);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to restart API CMD HW\n");
+		return err;
+	}
+
+	api_cmd_ctrl_init(chain);
+	api_cmd_set_num_cells(chain);
+	api_cmd_head_init(chain);
+
 	return 0;
 }
 
@@ -386,6 +557,7 @@ static int api_cmd_create_chain(struct hinic_api_cmd_chain **cmd_chain,
  **/
 static void api_cmd_destroy_chain(struct hinic_api_cmd_chain *chain)
 {
+	api_cmd_chain_hw_clean(chain);
 	api_cmd_destroy_cells(chain, chain->num_cells);
 	api_chain_free(chain);
 	kfree(chain);
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
index 39d33c7..0596b55 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
@@ -20,6 +20,44 @@
 
 #include "hinic_hw_if.h"
 
+#define HINIC_API_CMD_CHAIN_REQ_RESTART_SHIFT			1
+
+#define HINIC_API_CMD_CHAIN_REQ_RESTART_MASK			0x1
+
+#define HINIC_API_CMD_CHAIN_REQ_SET(val, member)		\
+	(((u32)(val) & HINIC_API_CMD_CHAIN_REQ_##member##_MASK) << \
+	 HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT)
+
+#define HINIC_API_CMD_CHAIN_REQ_GET(val, member)		\
+	(((val) >> HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT) &	\
+	 HINIC_API_CMD_CHAIN_REQ_##member##_MASK)
+
+#define HINIC_API_CMD_CHAIN_REQ_CLEAR(val, member)		\
+	((val) & (~(HINIC_API_CMD_CHAIN_REQ_##member##_MASK	\
+	 << HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT)))
+
+#define HINIC_API_CMD_CHAIN_CTRL_RESTART_WB_STAT_SHIFT		1
+#define HINIC_API_CMD_CHAIN_CTRL_XOR_ERR_SHIFT			2
+#define HINIC_API_CMD_CHAIN_CTRL_AEQE_EN_SHIFT			4
+#define HINIC_API_CMD_CHAIN_CTRL_AEQ_ID_SHIFT			8
+#define HINIC_API_CMD_CHAIN_CTRL_XOR_CHK_EN_SHIFT		28
+#define HINIC_API_CMD_CHAIN_CTRL_CELL_SIZE_SHIFT		30
+
+#define HINIC_API_CMD_CHAIN_CTRL_RESTART_WB_STAT_MASK		0x1
+#define HINIC_API_CMD_CHAIN_CTRL_XOR_ERR_MASK			0x1
+#define HINIC_API_CMD_CHAIN_CTRL_AEQE_EN_MASK			0x1
+#define HINIC_API_CMD_CHAIN_CTRL_AEQ_ID_MASK			0x3
+#define HINIC_API_CMD_CHAIN_CTRL_XOR_CHK_EN_MASK		0x3
+#define HINIC_API_CMD_CHAIN_CTRL_CELL_SIZE_MASK			0x3
+
+#define HINIC_API_CMD_CHAIN_CTRL_SET(val, member)		\
+	(((u32)(val) & HINIC_API_CMD_CHAIN_CTRL_##member##_MASK) << \
+	 HINIC_API_CMD_CHAIN_CTRL_##member##_SHIFT)
+
+#define HINIC_API_CMD_CHAIN_CTRL_CLEAR(val, member)		\
+	((val) & (~(HINIC_API_CMD_CHAIN_CTRL_##member##_MASK	\
+	 << HINIC_API_CMD_CHAIN_CTRL_##member##_SHIFT)))
+
 enum hinic_api_cmd_chain_type {
 	HINIC_API_CMD_WRITE_TO_MGMT_CPU	= 2,
 
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h
index 15b9409..6a12894 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h
@@ -33,4 +33,29 @@
 #define HINIC_CSR_PPF_ELECTION_ADDR(idx)		\
 	(HINIC_ELECTION_BASE +	(idx) * HINIC_PPF_ELECTION_STRIDE)
 
+/* API CMD registers */
+#define HINIC_CSR_API_CMD_BASE				0xF000
+
+#define HINIC_CSR_API_CMD_STRIDE			0x100
+
+#define HINIC_CSR_API_CMD_CHAIN_HEAD_HI_ADDR(idx)	\
+	(HINIC_CSR_API_CMD_BASE + 0x0 + (idx) * HINIC_CSR_API_CMD_STRIDE)
+
+#define HINIC_CSR_API_CMD_CHAIN_HEAD_LO_ADDR(idx)	\
+	(HINIC_CSR_API_CMD_BASE + 0x4 + (idx) * HINIC_CSR_API_CMD_STRIDE)
+
+#define HINIC_CSR_API_CMD_STATUS_HI_ADDR(idx)		\
+	(HINIC_CSR_API_CMD_BASE + 0x8 + (idx) * HINIC_CSR_API_CMD_STRIDE)
+
+#define HINIC_CSR_API_CMD_STATUS_LO_ADDR(idx)		\
+	(HINIC_CSR_API_CMD_BASE + 0xC + (idx) * HINIC_CSR_API_CMD_STRIDE)
+
+#define HINIC_CSR_API_CMD_CHAIN_NUM_CELLS_ADDR(idx)	\
+	(HINIC_CSR_API_CMD_BASE + 0x10 + (idx) * HINIC_CSR_API_CMD_STRIDE)
+
+#define HINIC_CSR_API_CMD_CHAIN_CTRL_ADDR(idx)		\
+	(HINIC_CSR_API_CMD_BASE + 0x14 + (idx) * HINIC_CSR_API_CMD_STRIDE)
+
+#define HINIC_CSR_API_CMD_CHAIN_REQ_ADDR(idx)		\
+	(HINIC_CSR_API_CMD_BASE + 0x20 + (idx) * HINIC_CSR_API_CMD_STRIDE)
 #endif
-- 
1.9.1

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH net 00/20] Huawei HiNIC Ethernet Driver Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:20 +0200
  [PATCH net 03/20] net/hinic: Initialize api cmd resources Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:20 +0200
  [PATCH net 04/20] net/hinic: Initialize api cmd hw Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 14/20] net/hinic: Initialize cmdq Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 10/20] net/hinic: Add logical Txq and Rxq Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 09/20] net/hinic: Add Rx mode and link event handler Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 17/20] net/hinic: Add cmdq completion handler Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 05/20] net/hinic: Add management messages Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 16/20] net/hinic: Add cmdq commands Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 12/20] net/hinic: Add qp resources Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 11/20] net/hinic: Add wq Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 07/20] net/hinic: Add aeqs Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 08/20] net/hinic: Add port management commands Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 15/20] net/hinic: Add ceqs Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 20/20] net/hinic: Add ethtool and stats Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
    Re: [PATCH net 20/20] net/hinic: Add ethtool and stats Andrew Lunn <andrew@lunn.ch> - 2017-07-12 17:50 +0200
      Re: [PATCH net 20/20] net/hinic: Add ethtool and stats "Aviad Krawczyk (A)" <aviad.krawczyk@huawei.com> - 2017-07-13 15:20 +0200
  [PATCH net 19/20] net/hinic: Add Tx operation Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  [PATCH net 13/20] net/hinic: Set qp context Aviad Krawczyk <aviad.krawczyk@huawei.com> - 2017-07-12 16:30 +0200
  Re: [PATCH net 00/20] Huawei HiNIC Ethernet Driver David Miller <davem@davemloft.net> - 2017-07-12 17:20 +0200

csiph-web