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

Commit 84e095d6 authored by Salil Mehta's avatar Salil Mehta Committed by David S. Miller
Browse files

net: hns3: Change PF to add ring-vect binding & resetQ to mailbox



This patch is required to support ring-vector binding and reset
of TQPs requested by the VF driver to the PF driver. Mailbox
handler is added with corresponding VF commands/messages to
handle the request.

Signed-off-by: default avatarSalil Mehta <salil.mehta@huawei.com>
Signed-off-by: default avatarlipeng <lipeng321@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dde1a86e
Loading
Loading
Loading
Loading
+48 −90
Original line number Diff line number Diff line
@@ -3256,49 +3256,48 @@ int hclge_rss_init_hw(struct hclge_dev *hdev)
	return ret;
}

int hclge_map_vport_ring_to_vector(struct hclge_vport *vport, int vector_id,
int hclge_bind_ring_with_vector(struct hclge_vport *vport,
				int vector_id, bool en,
				struct hnae3_ring_chain_node *ring_chain)
{
	struct hclge_dev *hdev = vport->back;
	struct hclge_ctrl_vector_chain_cmd *req;
	struct hnae3_ring_chain_node *node;
	struct hclge_desc desc;
	int ret;
	struct hclge_ctrl_vector_chain_cmd *req
		= (struct hclge_ctrl_vector_chain_cmd *)desc.data;
	enum hclge_cmd_status status;
	enum hclge_opcode_type op;
	u16 tqp_type_and_id;
	int i;

	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_ADD_RING_TO_VECTOR, false);

	req = (struct hclge_ctrl_vector_chain_cmd *)desc.data;
	op = en ? HCLGE_OPC_ADD_RING_TO_VECTOR : HCLGE_OPC_DEL_RING_TO_VECTOR;
	hclge_cmd_setup_basic_desc(&desc, op, false);
	req->int_vector_id = vector_id;

	i = 0;
	for (node = ring_chain; node; node = node->next) {
		u16 type_and_id = 0;

		hnae_set_field(type_and_id, HCLGE_INT_TYPE_M, HCLGE_INT_TYPE_S,
		tqp_type_and_id = le16_to_cpu(req->tqp_type_and_id[i]);
		hnae_set_field(tqp_type_and_id,  HCLGE_INT_TYPE_M,
			       HCLGE_INT_TYPE_S,
			       hnae_get_bit(node->flag, HNAE3_RING_TYPE_B));
		hnae_set_field(type_and_id, HCLGE_TQP_ID_M, HCLGE_TQP_ID_S,
			       node->tqp_index);
		hnae_set_field(type_and_id, HCLGE_INT_GL_IDX_M,
			       HCLGE_INT_GL_IDX_S,
			       hnae_get_bit(node->flag, HNAE3_RING_TYPE_B));
		req->tqp_type_and_id[i] = cpu_to_le16(type_and_id);
		req->vfid = vport->vport_id;

		hnae_set_field(tqp_type_and_id, HCLGE_TQP_ID_M,
			       HCLGE_TQP_ID_S, node->tqp_index);
		req->tqp_type_and_id[i] = cpu_to_le16(tqp_type_and_id);
		if (++i >= HCLGE_VECTOR_ELEMENTS_PER_CMD) {
			req->int_cause_num = HCLGE_VECTOR_ELEMENTS_PER_CMD;
			req->vfid = vport->vport_id;

			ret = hclge_cmd_send(&hdev->hw, &desc, 1);
			if (ret) {
			status = hclge_cmd_send(&hdev->hw, &desc, 1);
			if (status) {
				dev_err(&hdev->pdev->dev,
					"Map TQP fail, status is %d.\n",
					ret);
				return ret;
					status);
				return -EIO;
			}
			i = 0;

			hclge_cmd_setup_basic_desc(&desc,
						   HCLGE_OPC_ADD_RING_TO_VECTOR,
						   op,
						   false);
			req->int_vector_id = vector_id;
		}
@@ -3306,20 +3305,20 @@ int hclge_map_vport_ring_to_vector(struct hclge_vport *vport, int vector_id,

	if (i > 0) {
		req->int_cause_num = i;

		ret = hclge_cmd_send(&hdev->hw, &desc, 1);
		if (ret) {
		req->vfid = vport->vport_id;
		status = hclge_cmd_send(&hdev->hw, &desc, 1);
		if (status) {
			dev_err(&hdev->pdev->dev,
				"Map TQP fail, status is %d.\n", ret);
			return ret;
				"Map TQP fail, status is %d.\n", status);
			return -EIO;
		}
	}

	return 0;
}

static int hclge_map_handle_ring_to_vector(
		struct hnae3_handle *handle, int vector,
static int hclge_map_ring_to_vector(struct hnae3_handle *handle,
				    int vector,
				    struct hnae3_ring_chain_node *ring_chain)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
@@ -3329,24 +3328,20 @@ static int hclge_map_handle_ring_to_vector(
	vector_id = hclge_get_vector_index(hdev, vector);
	if (vector_id < 0) {
		dev_err(&hdev->pdev->dev,
			"Get vector index fail. ret =%d\n", vector_id);
			"Get vector index fail. vector_id =%d\n", vector_id);
		return vector_id;
	}

	return hclge_map_vport_ring_to_vector(vport, vector_id, ring_chain);
	return hclge_bind_ring_with_vector(vport, vector_id, true, ring_chain);
}

static int hclge_unmap_ring_from_vector(
	struct hnae3_handle *handle, int vector,
static int hclge_unmap_ring_frm_vector(struct hnae3_handle *handle,
				       int vector,
				       struct hnae3_ring_chain_node *ring_chain)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_dev *hdev = vport->back;
	struct hclge_ctrl_vector_chain_cmd *req;
	struct hnae3_ring_chain_node *node;
	struct hclge_desc desc;
	int i, vector_id;
	int ret;
	int vector_id, ret;

	vector_id = hclge_get_vector_index(hdev, vector);
	if (vector_id < 0) {
@@ -3355,54 +3350,17 @@ static int hclge_unmap_ring_from_vector(
		return vector_id;
	}

	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_DEL_RING_TO_VECTOR, false);

	req = (struct hclge_ctrl_vector_chain_cmd *)desc.data;
	req->int_vector_id = vector_id;

	i = 0;
	for (node = ring_chain; node; node = node->next) {
		u16 type_and_id = 0;

		hnae_set_field(type_and_id, HCLGE_INT_TYPE_M, HCLGE_INT_TYPE_S,
			       hnae_get_bit(node->flag, HNAE3_RING_TYPE_B));
		hnae_set_field(type_and_id, HCLGE_TQP_ID_M, HCLGE_TQP_ID_S,
			       node->tqp_index);
		hnae_set_field(type_and_id, HCLGE_INT_GL_IDX_M,
			       HCLGE_INT_GL_IDX_S,
			       hnae_get_bit(node->flag, HNAE3_RING_TYPE_B));

		req->tqp_type_and_id[i] = cpu_to_le16(type_and_id);
		req->vfid = vport->vport_id;

		if (++i >= HCLGE_VECTOR_ELEMENTS_PER_CMD) {
			req->int_cause_num = HCLGE_VECTOR_ELEMENTS_PER_CMD;

			ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	ret = hclge_bind_ring_with_vector(vport, vector_id, false, ring_chain);
	if (ret) {
				dev_err(&hdev->pdev->dev,
					"Unmap TQP fail, status is %d.\n",
		dev_err(&handle->pdev->dev,
			"Unmap ring from vector fail. vectorid=%d, ret =%d\n",
			vector_id,
			ret);
		return ret;
	}
			i = 0;
			hclge_cmd_setup_basic_desc(&desc,
						   HCLGE_OPC_DEL_RING_TO_VECTOR,
						   false);
			req->int_vector_id = vector_id;
		}
	}

	if (i > 0) {
		req->int_cause_num = i;

		ret = hclge_cmd_send(&hdev->hw, &desc, 1);
		if (ret) {
			dev_err(&hdev->pdev->dev,
				"Unmap TQP fail, status is %d.\n", ret);
			return ret;
		}
	}
	/* Free this MSIX or MSI vector */
	hclge_free_vector(hdev, vector_id);

	return 0;
}
@@ -4423,7 +4381,7 @@ static int hclge_get_reset_status(struct hclge_dev *hdev, u16 queue_id)
	return hnae_get_bit(req->ready_to_reset, HCLGE_TQP_RESET_B);
}

static void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_dev *hdev = vport->back;
@@ -4995,8 +4953,8 @@ static const struct hnae3_ae_ops hclge_ops = {
	.uninit_ae_dev = hclge_uninit_ae_dev,
	.init_client_instance = hclge_init_client_instance,
	.uninit_client_instance = hclge_uninit_client_instance,
	.map_ring_to_vector = hclge_map_handle_ring_to_vector,
	.unmap_ring_from_vector = hclge_unmap_ring_from_vector,
	.map_ring_to_vector = hclge_map_ring_to_vector,
	.unmap_ring_from_vector = hclge_unmap_ring_frm_vector,
	.get_vector = hclge_get_vector,
	.set_promisc_mode = hclge_set_promisc_mode,
	.set_loopback = hclge_set_loopback,
+5 −2
Original line number Diff line number Diff line
@@ -539,8 +539,10 @@ int hclge_cfg_func_mta_filter(struct hclge_dev *hdev,
			      u8 func_id,
			      bool enable);
struct hclge_vport *hclge_get_vport(struct hnae3_handle *handle);
int hclge_map_vport_ring_to_vector(struct hclge_vport *vport, int vector,
int hclge_bind_ring_with_vector(struct hclge_vport *vport,
				int vector_id, bool en,
				struct hnae3_ring_chain_node *ring_chain);

static inline int hclge_get_queue_id(struct hnae3_queue *queue)
{
	struct hclge_tqp *tqp = container_of(queue, struct hclge_tqp, q);
@@ -556,4 +558,5 @@ int hclge_buffer_alloc(struct hclge_dev *hdev);
int hclge_rss_init_hw(struct hclge_dev *hdev);

void hclge_mbx_handler(struct hclge_dev *hdev);
void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id);
#endif
+106 −0
Original line number Diff line number Diff line
@@ -79,6 +79,91 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len,
	return status;
}

static void hclge_free_vector_ring_chain(struct hnae3_ring_chain_node *head)
{
	struct hnae3_ring_chain_node *chain_tmp, *chain;

	chain = head->next;

	while (chain) {
		chain_tmp = chain->next;
		kzfree(chain);
		chain = chain_tmp;
	}
}

/* hclge_get_ring_chain_from_mbx: get ring type & tqpid from mailbox message
 * msg[0]: opcode
 * msg[1]: <not relevant to this function>
 * msg[2]: ring_num
 * msg[3]: first ring type (TX|RX)
 * msg[4]: first tqp id
 * msg[5] ~ msg[14]: other ring type and tqp id
 */
static int hclge_get_ring_chain_from_mbx(
			struct hclge_mbx_vf_to_pf_cmd *req,
			struct hnae3_ring_chain_node *ring_chain,
			struct hclge_vport *vport)
{
#define HCLGE_RING_NODE_VARIABLE_NUM		3
#define HCLGE_RING_MAP_MBX_BASIC_MSG_NUM	3
	struct hnae3_ring_chain_node *cur_chain, *new_chain;
	int ring_num;
	int i;

	ring_num = req->msg[2];

	hnae_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, req->msg[3]);
	ring_chain->tqp_index =
			hclge_get_queue_id(vport->nic.kinfo.tqp[req->msg[4]]);

	cur_chain = ring_chain;

	for (i = 1; i < ring_num; i++) {
		new_chain = kzalloc(sizeof(*new_chain), GFP_KERNEL);
		if (!new_chain)
			goto err;

		hnae_set_bit(new_chain->flag, HNAE3_RING_TYPE_B,
			     req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i +
			     HCLGE_RING_MAP_MBX_BASIC_MSG_NUM]);

		new_chain->tqp_index =
		hclge_get_queue_id(vport->nic.kinfo.tqp
			[req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i +
			HCLGE_RING_MAP_MBX_BASIC_MSG_NUM + 1]]);

		cur_chain->next = new_chain;
		cur_chain = new_chain;
	}

	return 0;
err:
	hclge_free_vector_ring_chain(ring_chain);
	return -ENOMEM;
}

static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en,
					     struct hclge_mbx_vf_to_pf_cmd *req)
{
	struct hnae3_ring_chain_node ring_chain;
	int vector_id = req->msg[1];
	int ret;

	memset(&ring_chain, 0, sizeof(ring_chain));
	ret = hclge_get_ring_chain_from_mbx(req, &ring_chain, vport);
	if (ret)
		return ret;

	ret = hclge_bind_ring_with_vector(vport, vector_id, en, &ring_chain);
	if (ret)
		return ret;

	hclge_free_vector_ring_chain(&ring_chain);

	return 0;
}

static int hclge_set_vf_promisc_mode(struct hclge_vport *vport,
				     struct hclge_mbx_vf_to_pf_cmd *req)
{
@@ -224,6 +309,16 @@ static int hclge_get_link_info(struct hclge_vport *vport,
				  HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid);
}

static void hclge_reset_vf_queue(struct hclge_vport *vport,
				 struct hclge_mbx_vf_to_pf_cmd *mbx_req)
{
	u16 queue_id;

	memcpy(&queue_id, &mbx_req->msg[2], sizeof(queue_id));

	hclge_reset_tqp(&vport->nic, queue_id);
}

void hclge_mbx_handler(struct hclge_dev *hdev)
{
	struct hclge_cmq_ring *crq = &hdev->hw.cmq.crq;
@@ -241,6 +336,14 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
		vport = &hdev->vport[req->mbx_src_vfid];

		switch (req->msg[0]) {
		case HCLGE_MBX_MAP_RING_TO_VECTOR:
			ret = hclge_map_unmap_ring_to_vf_vector(vport, true,
								req);
			break;
		case HCLGE_MBX_UNMAP_RING_TO_VECTOR:
			ret = hclge_map_unmap_ring_to_vf_vector(vport, false,
								req);
			break;
		case HCLGE_MBX_SET_PROMISC_MODE:
			ret = hclge_set_vf_promisc_mode(vport, req);
			if (ret)
@@ -290,6 +393,9 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
					"PF fail(%d) to get link stat for VF\n",
					ret);
			break;
		case HCLGE_MBX_QUEUE_RESET:
			hclge_reset_vf_queue(vport, req);
			break;
		default:
			dev_err(&hdev->pdev->dev,
				"un-supported mailbox message, code = %d\n",