Commit 97dcb914 authored by Fan Gong's avatar Fan Gong Committed by Paolo Abeni
Browse files

hinic3: Queue pair context initialization

parent 73f37a7e
Loading
Loading
Loading
Loading
+88 −0
Original line number Diff line number Diff line
@@ -336,3 +336,91 @@ int hinic3_func_rx_tx_flush(struct hinic3_hwdev *hwdev)

	return ret;
}

static int get_hw_rx_buf_size_idx(int rx_buf_sz, u16 *buf_sz_idx)
{
	/* Supported RX buffer sizes in bytes. Configured by array index. */
	static const int supported_sizes[16] = {
		[0] = 32,     [1] = 64,     [2] = 96,     [3] = 128,
		[4] = 192,    [5] = 256,    [6] = 384,    [7] = 512,
		[8] = 768,    [9] = 1024,   [10] = 1536,  [11] = 2048,
		[12] = 3072,  [13] = 4096,  [14] = 8192,  [15] = 16384,
	};
	u16 idx;

	/* Scan from biggest to smallest. Choose supported size that is equal or
	 * smaller. For smaller value HW will under-utilize posted buffers. For
	 * bigger value HW may overrun posted buffers.
	 */
	idx = ARRAY_SIZE(supported_sizes);
	while (idx > 0) {
		idx--;
		if (supported_sizes[idx] <= rx_buf_sz) {
			*buf_sz_idx = idx;
			return 0;
		}
	}

	return -EINVAL;
}

int hinic3_set_root_ctxt(struct hinic3_hwdev *hwdev, u32 rq_depth, u32 sq_depth,
			 int rx_buf_sz)
{
	struct comm_cmd_set_root_ctxt root_ctxt = {};
	struct mgmt_msg_params msg_params = {};
	u16 buf_sz_idx;
	int err;

	err = get_hw_rx_buf_size_idx(rx_buf_sz, &buf_sz_idx);
	if (err)
		return err;

	root_ctxt.func_id = hinic3_global_func_id(hwdev);

	root_ctxt.set_cmdq_depth = 0;
	root_ctxt.cmdq_depth = 0;

	root_ctxt.lro_en = 1;

	root_ctxt.rq_depth  = ilog2(rq_depth);
	root_ctxt.rx_buf_sz = buf_sz_idx;
	root_ctxt.sq_depth  = ilog2(sq_depth);

	mgmt_msg_params_init_default(&msg_params, &root_ctxt,
				     sizeof(root_ctxt));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_SET_VAT, &msg_params);
	if (err || root_ctxt.head.status) {
		dev_err(hwdev->dev,
			"Failed to set root context, err: %d, status: 0x%x\n",
			err, root_ctxt.head.status);
		return -EFAULT;
	}

	return 0;
}

int hinic3_clean_root_ctxt(struct hinic3_hwdev *hwdev)
{
	struct comm_cmd_set_root_ctxt root_ctxt = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	root_ctxt.func_id = hinic3_global_func_id(hwdev);

	mgmt_msg_params_init_default(&msg_params, &root_ctxt,
				     sizeof(root_ctxt));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_SET_VAT, &msg_params);
	if (err || root_ctxt.head.status) {
		dev_err(hwdev->dev,
			"Failed to set root context, err: %d, status: 0x%x\n",
			err, root_ctxt.head.status);
		return -EFAULT;
	}

	return 0;
}
+3 −0
Original line number Diff line number Diff line
@@ -40,5 +40,8 @@ int hinic3_set_wq_page_size(struct hinic3_hwdev *hwdev, u16 func_idx,
			    u32 page_size);
int hinic3_set_cmdq_depth(struct hinic3_hwdev *hwdev, u16 cmdq_depth);
int hinic3_func_rx_tx_flush(struct hinic3_hwdev *hwdev);
int hinic3_set_root_ctxt(struct hinic3_hwdev *hwdev, u32 rq_depth, u32 sq_depth,
			 int rx_buf_sz);
int hinic3_clean_root_ctxt(struct hinic3_hwdev *hwdev);

#endif
+20 −0
Original line number Diff line number Diff line
@@ -56,6 +56,19 @@ struct l2nic_cmd_update_mac {
	u8                   new_mac[ETH_ALEN];
};

struct l2nic_cmd_set_ci_attr {
	struct mgmt_msg_head msg_head;
	u16                  func_idx;
	u8                   dma_attr_off;
	u8                   pending_limit;
	u8                   coalescing_time;
	u8                   intr_en;
	u16                  intr_idx;
	u32                  l2nic_sqn;
	u32                  rsvd;
	u64                  ci_addr;
};

struct l2nic_cmd_force_pkt_drop {
	struct mgmt_msg_head msg_head;
	u8                   port;
@@ -82,6 +95,13 @@ enum l2nic_cmd {
	L2NIC_CMD_MAX                 = 256,
};

/* NIC CMDQ MODE */
enum l2nic_ucode_cmd {
	L2NIC_UCODE_CMD_MODIFY_QUEUE_CTX  = 0,
	L2NIC_UCODE_CMD_CLEAN_QUEUE_CTX   = 1,
	L2NIC_UCODE_CMD_SET_RSS_INDIR_TBL = 4,
};

enum hinic3_nic_feature_cap {
	HINIC3_NIC_F_CSUM           = BIT(0),
	HINIC3_NIC_F_SCTP_CRC       = BIT(1),
+42 −0
Original line number Diff line number Diff line
@@ -221,6 +221,39 @@ static void hinic3_free_channel_resources(struct net_device *netdev,
	hinic3_free_qps(nic_dev, qp_params);
}

static int hinic3_open_channel(struct net_device *netdev)
{
	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
	int err;

	err = hinic3_init_qp_ctxts(nic_dev);
	if (err) {
		netdev_err(netdev, "Failed to init qps\n");
		return err;
	}

	err = hinic3_qps_irq_init(netdev);
	if (err) {
		netdev_err(netdev, "Failed to init txrxq irq\n");
		goto err_free_qp_ctxts;
	}

	return 0;

err_free_qp_ctxts:
	hinic3_free_qp_ctxts(nic_dev);

	return err;
}

static void hinic3_close_channel(struct net_device *netdev)
{
	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);

	hinic3_qps_irq_uninit(netdev);
	hinic3_free_qp_ctxts(nic_dev);
}

static int hinic3_open(struct net_device *netdev)
{
	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -246,8 +279,16 @@ static int hinic3_open(struct net_device *netdev)

	hinic3_init_qps(nic_dev, &qp_params);

	err = hinic3_open_channel(netdev);
	if (err)
		goto err_uninit_qps;

	return 0;

err_uninit_qps:
	hinic3_uninit_qps(nic_dev, &qp_params);
	hinic3_free_channel_resources(netdev, &qp_params, &nic_dev->q_params);

err_destroy_num_qps:
	hinic3_destroy_num_qps(netdev);
err_free_nicio_res:
@@ -261,6 +302,7 @@ static int hinic3_close(struct net_device *netdev)
	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
	struct hinic3_dyna_qp_params qp_params;

	hinic3_close_channel(netdev);
	hinic3_uninit_qps(nic_dev, &qp_params);
	hinic3_free_channel_resources(netdev, &qp_params, &nic_dev->q_params);

+35 −0
Original line number Diff line number Diff line
@@ -229,6 +229,41 @@ int hinic3_update_mac(struct hinic3_hwdev *hwdev, const u8 *old_mac,
			err, mac_info.msg_head.status);
		return -EIO;
	}

	return 0;
}

int hinic3_set_ci_table(struct hinic3_hwdev *hwdev, struct hinic3_sq_attr *attr)
{
	struct l2nic_cmd_set_ci_attr cons_idx_attr = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	cons_idx_attr.func_idx = hinic3_global_func_id(hwdev);
	cons_idx_attr.dma_attr_off  = attr->dma_attr_off;
	cons_idx_attr.pending_limit = attr->pending_limit;
	cons_idx_attr.coalescing_time  = attr->coalescing_time;

	if (attr->intr_en) {
		cons_idx_attr.intr_en = attr->intr_en;
		cons_idx_attr.intr_idx = attr->intr_idx;
	}

	cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
	cons_idx_attr.ci_addr = attr->ci_dma_base;

	mgmt_msg_params_init_default(&msg_params, &cons_idx_attr,
				     sizeof(cons_idx_attr));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_L2NIC,
				       L2NIC_CMD_SET_SQ_CI_ATTR, &msg_params);
	if (err || cons_idx_attr.msg_head.status) {
		dev_err(hwdev->dev,
			"Failed to set ci attribute table, err: %d, status: 0x%x\n",
			err, cons_idx_attr.msg_head.status);
		return -EFAULT;
	}

	return 0;
}

Loading