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

Commit 1e007181 authored by Xue Chaojing's avatar Xue Chaojing Committed by David S. Miller
Browse files

hinic: add LRO support



This patch adds LRO support for the HiNIC driver.

Reported-by: default avatarkbuild test robot <lkp@intel.com>
Reviewed-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: default avatarXue Chaojing <xuechaojing@huawei.com>
Reviewed-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 600bb031
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -313,6 +313,8 @@ static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth,
	hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT;
	hw_ioctxt.cmdq_depth = 0;

	hw_ioctxt.lro_en = 1;

	hw_ioctxt.rq_depth  = ilog2(rq_depth);

	hw_ioctxt.rx_buf_sz_idx = HINIC_RX_BUF_SZ_IDX;
+7 −1
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ enum hinic_port_cmd {

	HINIC_PORT_CMD_GET_LINK_STATE   = 24,

	HINIC_PORT_CMD_SET_LRO		= 25,

	HINIC_PORT_CMD_SET_RX_CSUM	= 26,

	HINIC_PORT_CMD_SET_PORT_STATE   = 41,
@@ -62,7 +64,11 @@ enum hinic_port_cmd {

	HINIC_PORT_CMD_SET_TSO          = 112,

	HINIC_PORT_CMD_SET_RQ_IQ_MAP	= 115,

	HINIC_PORT_CMD_GET_CAP          = 170,

	HINIC_PORT_CMD_SET_LRO_TIMER	= 244,
};

enum hinic_mgmt_msg_cmd {
@@ -106,7 +112,7 @@ struct hinic_cmd_hw_ioctxt {
	u8      set_cmdq_depth;
	u8      cmdq_depth;

	u8      rsvd2;
	u8      lro_en;
	u8      rsvd3;
	u8      rsvd4;
	u8      rsvd5;
+60 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@

enum io_cmd {
	IO_CMD_MODIFY_QUEUE_CTXT = 0,
	IO_CMD_CLEAN_QUEUE_CTXT,
};

static void init_db_area_idx(struct hinic_free_db_area *free_db_area)
@@ -210,6 +211,59 @@ static int write_qp_ctxts(struct hinic_func_to_io *func_to_io, u16 base_qpn,
		write_rq_ctxts(func_to_io, base_qpn, num_qps));
}

static int hinic_clean_queue_offload_ctxt(struct hinic_func_to_io *func_to_io,
					  enum hinic_qp_ctxt_type ctxt_type)
{
	struct hinic_hwif *hwif = func_to_io->hwif;
	struct hinic_clean_queue_ctxt *ctxt_block;
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_cmdq_buf cmdq_buf;
	u64 out_param = 0;
	int err;

	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmdq_buf);
	if (err) {
		dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
		return err;
	}

	ctxt_block = cmdq_buf.buf;
	ctxt_block->cmdq_hdr.num_queues = func_to_io->max_qps;
	ctxt_block->cmdq_hdr.queue_type = ctxt_type;
	ctxt_block->cmdq_hdr.addr_offset = 0;

	/* TSO/LRO ctxt size: 0x0:0B; 0x1:160B; 0x2:200B; 0x3:240B */
	ctxt_block->ctxt_size = 0x3;

	hinic_cpu_to_be32(ctxt_block, sizeof(*ctxt_block));

	cmdq_buf.size = sizeof(*ctxt_block);

	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
				     IO_CMD_CLEAN_QUEUE_CTXT,
				     &cmdq_buf, &out_param);

	if (err || out_param) {
		dev_err(&pdev->dev, "Failed to clean offload ctxts, err: %d, out_param: 0x%llx\n",
			err, out_param);

		err = -EFAULT;
	}

	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmdq_buf);

	return err;
}

static int hinic_clean_qp_offload_ctxt(struct hinic_func_to_io *func_to_io)
{
	/* clean LRO/TSO context space */
	return (hinic_clean_queue_offload_ctxt(func_to_io,
					       HINIC_QP_CTXT_TYPE_SQ) ||
		hinic_clean_queue_offload_ctxt(func_to_io,
					       HINIC_QP_CTXT_TYPE_RQ));
}

/**
 * init_qp - Initialize a Queue Pair
 * @func_to_io: func to io channel that holds the IO components
@@ -381,6 +435,12 @@ int hinic_io_create_qps(struct hinic_func_to_io *func_to_io,
		goto err_write_qp_ctxts;
	}

	err = hinic_clean_qp_offload_ctxt(func_to_io);
	if (err) {
		dev_err(&pdev->dev, "Failed to clean QP contexts space\n");
		goto err_write_qp_ctxts;
	}

	return 0;

err_write_qp_ctxts:
+5 −0
Original line number Diff line number Diff line
@@ -201,6 +201,11 @@ struct hinic_rq_ctxt {
	u32     wq_block_lo_pfn;
};

struct hinic_clean_queue_ctxt {
	struct hinic_qp_ctxt_header	cmdq_hdr;
	u32				ctxt_size;
};

struct hinic_sq_ctxt_block {
	struct hinic_qp_ctxt_header hdr;
	struct hinic_sq_ctxt sq_ctxt[HINIC_Q_CTXT_MAX];
+21 −1
Original line number Diff line number Diff line
@@ -219,6 +219,26 @@
#define HINIC_MSS_DEFAULT		        0x3E00
#define HINIC_MSS_MIN		                0x50

#define RQ_CQE_STATUS_NUM_LRO_SHIFT		16
#define RQ_CQE_STATUS_NUM_LRO_MASK		0xFFU

#define RQ_CQE_STATUS_GET(val, member)		(((val) >> \
			RQ_CQE_STATUS_##member##_SHIFT) & \
			RQ_CQE_STATUS_##member##_MASK)

#define HINIC_GET_RX_NUM_LRO(status)	\
		RQ_CQE_STATUS_GET(status, NUM_LRO)

#define RQ_CQE_OFFOLAD_TYPE_PKT_TYPE_SHIFT		0
#define RQ_CQE_OFFOLAD_TYPE_PKT_TYPE_MASK		0xFFFU

#define RQ_CQE_OFFOLAD_TYPE_GET(val, member)		(((val) >> \
				RQ_CQE_OFFOLAD_TYPE_##member##_SHIFT) & \
				RQ_CQE_OFFOLAD_TYPE_##member##_MASK)

#define HINIC_GET_RX_PKT_TYPE(offload_type)	\
			RQ_CQE_OFFOLAD_TYPE_GET(offload_type, PKT_TYPE)

enum hinic_l4offload_type {
	HINIC_L4_OFF_DISABLE            = 0,
	HINIC_TCP_OFFLOAD_ENABLE        = 1,
@@ -372,7 +392,7 @@ struct hinic_rq_cqe {
	u32     status;
	u32     len;

	u32     rsvd2;
	u32     offload_type;
	u32     rsvd3;
	u32     rsvd4;
	u32     rsvd5;
Loading