All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jingjing Wu <jingjing.wu@intel.com>
To: bruce.richardson@intel.com
Cc: dev@dpdk.org
Subject: [PATCH v4 1/2] i40evf: allocate virtchnl cmd buffer for each vf
Date: Wed,  9 Mar 2016 14:00:48 +0800	[thread overview]
Message-ID: <1457503249-14878-2-git-send-email-jingjing.wu@intel.com> (raw)
In-Reply-To: <1457503249-14878-1-git-send-email-jingjing.wu@intel.com>

Currently, i40evf PMD uses a global static buffer to send virtchnl
command to host driver. It is shared by multi VFs.
This patch changed to allocate virtchnl cmd buffer for each VF.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.h    |   2 +
 drivers/net/i40e/i40e_ethdev_vf.c | 178 +++++++++++++++-----------------------
 2 files changed, 71 insertions(+), 109 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index a9b805e..8cd6126 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -497,7 +497,9 @@ struct i40e_vf {
 	bool link_up;
 	bool vf_reset;
 	volatile uint32_t pend_cmd; /* pending command not finished yet */
+	uint32_t cmd_retval; /* return value of the cmd response from PF */
 	u16 pend_msg; /* flags indicates events from pf not handled yet */
+	uint8_t *aq_resp; /* buffer to store the adminq response from PF */
 
 	/* VSI info */
 	struct i40e_virtchnl_vf_resource *vf_res; /* All VSIs */
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 6185ee8..90edeb5 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -103,9 +103,6 @@ enum i40evf_aq_result {
 	I40EVF_MSG_CMD,      /* Read async command result */
 };
 
-/* A share buffer to store the command result from PF driver */
-static uint8_t cmd_result_buffer[I40E_AQ_BUF_SZ];
-
 static int i40evf_dev_configure(struct rte_eth_dev *dev);
 static int i40evf_dev_start(struct rte_eth_dev *dev);
 static void i40evf_dev_stop(struct rte_eth_dev *dev);
@@ -217,31 +214,37 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 };
 
 /*
- * Parse admin queue message.
- *
- * return value:
- *  < 0: meet error
- *  0: read sys msg
- *  > 0: read cmd result
+ * Read data in admin queue to get msg from pf driver
  */
 static enum i40evf_aq_result
-i40evf_parse_pfmsg(struct i40e_vf *vf,
-		   struct i40e_arq_event_info *event,
-		   struct i40evf_arq_msg_info *data)
+i40evf_read_pfmsg(struct rte_eth_dev *dev, struct i40evf_arq_msg_info *data)
 {
-	enum i40e_virtchnl_ops opcode = (enum i40e_virtchnl_ops)\
-			rte_le_to_cpu_32(event->desc.cookie_high);
-	enum i40e_status_code retval = (enum i40e_status_code)\
-			rte_le_to_cpu_32(event->desc.cookie_low);
-	enum i40evf_aq_result ret = I40EVF_MSG_CMD;
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	struct i40e_arq_event_info event;
+	enum i40e_virtchnl_ops opcode;
+	enum i40e_status_code retval;
+	int ret;
+	enum i40evf_aq_result result = I40EVF_MSG_NON;
+
+	event.buf_len = data->buf_len;
+	event.msg_buf = data->msg;
+	ret = i40e_clean_arq_element(hw, &event, NULL);
+	/* Can't read any msg from adminQ */
+	if (ret) {
+		if (ret != I40E_ERR_ADMIN_QUEUE_NO_WORK)
+			result = I40EVF_MSG_ERR;
+		return result;
+	}
 
+	opcode = (enum i40e_virtchnl_ops)rte_le_to_cpu_32(event.desc.cookie_high);
+	retval = (enum i40e_status_code)rte_le_to_cpu_32(event.desc.cookie_low);
 	/* pf sys event */
 	if (opcode == I40E_VIRTCHNL_OP_EVENT) {
 		struct i40e_virtchnl_pf_event *vpe =
-			(struct i40e_virtchnl_pf_event *)event->msg_buf;
+			(struct i40e_virtchnl_pf_event *)event.msg_buf;
 
-		/* Initialize ret to sys event */
-		ret = I40EVF_MSG_SYS;
+		result = I40EVF_MSG_SYS;
 		switch (vpe->event) {
 		case I40E_VIRTCHNL_EVENT_LINK_CHANGE:
 			vf->link_up =
@@ -266,74 +269,17 @@ i40evf_parse_pfmsg(struct i40e_vf *vf,
 		}
 	} else {
 		/* async reply msg on command issued by vf previously */
-		ret = I40EVF_MSG_CMD;
+		result = I40EVF_MSG_CMD;
 		/* Actual data length read from PF */
-		data->msg_len = event->msg_len;
+		data->msg_len = event.msg_len;
 	}
-	/* fill the ops and result to notify VF */
+
 	data->result = retval;
 	data->ops = opcode;
 
-	return ret;
-}
-
-/*
- * Read data in admin queue to get msg from pf driver
- */
-static enum i40evf_aq_result
-i40evf_read_pfmsg(struct rte_eth_dev *dev, struct i40evf_arq_msg_info *data)
-{
-	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-	struct i40e_arq_event_info event;
-	int ret;
-	enum i40evf_aq_result result = I40EVF_MSG_NON;
-
-	event.buf_len = data->buf_len;
-	event.msg_buf = data->msg;
-	ret = i40e_clean_arq_element(hw, &event, NULL);
-	/* Can't read any msg from adminQ */
-	if (ret) {
-		if (ret == I40E_ERR_ADMIN_QUEUE_NO_WORK)
-			result = I40EVF_MSG_NON;
-		else
-			result = I40EVF_MSG_ERR;
-		return result;
-	}
-
-	/* Parse the event */
-	result = i40evf_parse_pfmsg(vf, &event, data);
-
 	return result;
 }
 
-/*
- * Polling read until command result return from pf driver or meet error.
- */
-static int
-i40evf_wait_cmd_done(struct rte_eth_dev *dev,
-		     struct i40evf_arq_msg_info *data)
-{
-	int i = 0;
-	enum i40evf_aq_result ret;
-
-#define MAX_TRY_TIMES 20
-#define ASQ_DELAY_MS  100
-	do {
-		/* Delay some time first */
-		rte_delay_ms(ASQ_DELAY_MS);
-		ret = i40evf_read_pfmsg(dev, data);
-		if (ret == I40EVF_MSG_CMD)
-			return 0;
-		else if (ret == I40EVF_MSG_ERR)
-			return -1;
-
-		/* If don't read msg or read sys event, continue */
-	} while(i++ < MAX_TRY_TIMES);
-
-	return -1;
-}
-
 /**
  * clear current command. Only call in case execute
  * _atomic_set_cmd successfully.
@@ -360,13 +306,18 @@ _atomic_set_cmd(struct i40e_vf *vf, enum i40e_virtchnl_ops ops)
 	return !ret;
 }
 
+#define MAX_TRY_TIMES 200
+#define ASQ_DELAY_MS  10
+
 static int
 i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-	int err = -1;
 	struct i40evf_arq_msg_info info;
+	enum i40evf_aq_result ret;
+	int err = -1;
+	int i = 0;
 
 	if (_atomic_set_cmd(vf, args->ops))
 		return -1;
@@ -384,19 +335,21 @@ i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args)
 		return err;
 	}
 
-	err = i40evf_wait_cmd_done(dev, &info);
-	/* read message and it's expected one */
-	if (!err && args->ops == info.ops)
-		_clear_cmd(vf);
-	else if (err) {
-		PMD_DRV_LOG(ERR, "Failed to read message from AdminQ");
-		_clear_cmd(vf);
-	}
-	else if (args->ops != info.ops)
-		PMD_DRV_LOG(ERR, "command mismatch, expect %u, get %u",
-			    args->ops, info.ops);
+	do {
+		ret = i40evf_read_pfmsg(dev, &info);
+		if (ret == I40EVF_MSG_CMD) {
+			err = 0;
+			break;
+		} else if (ret == I40EVF_MSG_ERR) {
+			err = -1;
+			break;
+		}
+		rte_delay_ms(ASQ_DELAY_MS);
+		/* If don't read msg or read sys event, continue */
+	} while (i++ < MAX_TRY_TIMES);
+	_clear_cmd(vf);
 
-	return err | info.result;
+	return err | vf->cmd_retval;
 }
 
 /*
@@ -416,7 +369,7 @@ i40evf_check_api_version(struct rte_eth_dev *dev)
 	args.ops = I40E_VIRTCHNL_OP_VERSION;
 	args.in_args = (uint8_t *)&version;
 	args.in_args_size = sizeof(version);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 
 	err = i40evf_execute_vf_cmd(dev, &args);
@@ -454,7 +407,7 @@ i40evf_get_vf_resource(struct rte_eth_dev *dev)
 	uint32_t caps, len;
 
 	args.ops = I40E_VIRTCHNL_OP_GET_VF_RESOURCES;
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 	if (PF_IS_V11(vf)) {
 		caps = I40E_VIRTCHNL_VF_OFFLOAD_L2 |
@@ -507,7 +460,7 @@ i40evf_config_promisc(struct rte_eth_dev *dev,
 	args.ops = I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE;
 	args.in_args = (uint8_t *)&promisc;
 	args.in_args_size = sizeof(promisc);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 
 	err = i40evf_execute_vf_cmd(dev, &args);
@@ -534,7 +487,7 @@ i40evf_config_vlan_offload(struct rte_eth_dev *dev,
 	args.ops = (enum i40e_virtchnl_ops)I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD;
 	args.in_args = (uint8_t *)&offload;
 	args.in_args_size = sizeof(offload);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 
 	err = i40evf_execute_vf_cmd(dev, &args);
@@ -565,7 +518,7 @@ i40evf_config_vlan_pvid(struct rte_eth_dev *dev,
 	args.ops = (enum i40e_virtchnl_ops)I40E_VIRTCHNL_OP_CFG_VLAN_PVID;
 	args.in_args = (uint8_t *)&tpid_info;
 	args.in_args_size = sizeof(tpid_info);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 
 	err = i40evf_execute_vf_cmd(dev, &args);
@@ -644,7 +597,7 @@ i40evf_configure_vsi_queues(struct rte_eth_dev *dev)
 	args.ops = I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES;
 	args.in_args = (uint8_t *)vc_vqci;
 	args.in_args_size = size;
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 	ret = i40evf_execute_vf_cmd(dev, &args);
 	if (ret)
@@ -697,7 +650,7 @@ i40evf_configure_vsi_queues_ext(struct rte_eth_dev *dev)
 		(enum i40e_virtchnl_ops)I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EXT;
 	args.in_args = (uint8_t *)vc_vqcei;
 	args.in_args_size = size;
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 	ret = i40evf_execute_vf_cmd(dev, &args);
 	if (ret)
@@ -759,7 +712,7 @@ i40evf_config_irq_map(struct rte_eth_dev *dev)
 	args.ops = I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP;
 	args.in_args = (u8 *)cmd_buffer;
 	args.in_args_size = sizeof(cmd_buffer);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err)
@@ -790,7 +743,7 @@ i40evf_switch_queue(struct rte_eth_dev *dev, bool isrx, uint16_t qid,
 		args.ops = I40E_VIRTCHNL_OP_DISABLE_QUEUES;
 	args.in_args = (u8 *)&queue_select;
 	args.in_args_size = sizeof(queue_select);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err)
@@ -882,7 +835,7 @@ i40evf_add_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 	args.ops = I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS;
 	args.in_args = cmd_buffer;
 	args.in_args_size = sizeof(cmd_buffer);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err)
@@ -919,7 +872,7 @@ i40evf_del_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 	args.ops = I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS;
 	args.in_args = cmd_buffer;
 	args.in_args_size = sizeof(cmd_buffer);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err)
@@ -942,7 +895,7 @@ i40evf_update_stats(struct rte_eth_dev *dev, struct i40e_eth_stats **pstats)
 	args.ops = I40E_VIRTCHNL_OP_GET_STATS;
 	args.in_args = (u8 *)&q_stats;
 	args.in_args_size = sizeof(q_stats);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 
 	err = i40evf_execute_vf_cmd(dev, &args);
@@ -1036,7 +989,7 @@ i40evf_add_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
 	args.ops = I40E_VIRTCHNL_OP_ADD_VLAN;
 	args.in_args = (u8 *)&cmd_buffer;
 	args.in_args_size = sizeof(cmd_buffer);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err)
@@ -1063,7 +1016,7 @@ i40evf_del_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
 	args.ops = I40E_VIRTCHNL_OP_DEL_VLAN;
 	args.in_args = (u8 *)&cmd_buffer;
 	args.in_args_size = sizeof(cmd_buffer);
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err)
@@ -1075,6 +1028,7 @@ i40evf_del_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
 static int
 i40evf_get_link_status(struct rte_eth_dev *dev, struct rte_eth_link *link)
 {
+	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	int err;
 	struct vf_cmd_info args;
 	struct rte_eth_link *new_link;
@@ -1082,7 +1036,7 @@ i40evf_get_link_status(struct rte_eth_dev *dev, struct rte_eth_link *link)
 	args.ops = (enum i40e_virtchnl_ops)I40E_VIRTCHNL_OP_GET_LINK_STAT;
 	args.in_args = NULL;
 	args.in_args_size = 0;
-	args.out_buffer = cmd_result_buffer;
+	args.out_buffer = vf->aq_resp;
 	args.out_size = I40E_AQ_BUF_SZ;
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err) {
@@ -1177,7 +1131,6 @@ i40evf_init_vf(struct rte_eth_dev *dev)
 		goto err;
 	}
 
-
 	/* Reset VF and wait until it's complete */
 	if (i40evf_reset_vf(hw)) {
 		PMD_INIT_LOG(ERR, "reset NIC failed");
@@ -1195,6 +1148,11 @@ i40evf_init_vf(struct rte_eth_dev *dev)
 		PMD_INIT_LOG(ERR, "init_adminq failed");
 		return -1;
 	}
+	vf->aq_resp = rte_zmalloc("vf_aq_resp", I40E_AQ_BUF_SZ, 0);
+	if (!vf->aq_resp) {
+		PMD_INIT_LOG(ERR, "unable to allocate vf_aq_resp memory");
+			goto err_aq;
+	}
 	if (i40evf_check_api_version(dev) != 0) {
 		PMD_INIT_LOG(ERR, "check_api version failed");
 		goto err_aq;
@@ -1259,6 +1217,8 @@ i40evf_uninit_vf(struct rte_eth_dev *dev)
 		i40evf_dev_close(dev);
 	rte_free(vf->vf_res);
 	vf->vf_res = NULL;
+	rte_free(vf->aq_resp);
+	vf->aq_resp = NULL;
 
 	return 0;
 }
-- 
2.4.0

  reply	other threads:[~2016-03-09  6:00 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-13 12:31 [PATCH 0/2] i40evf: support interrupt based pf reset request Jingjing Wu
2016-01-13 12:31 ` [PATCH 1/2] i40evf: allocate virtchnl cmd buffer for each vf Jingjing Wu
2016-01-13 12:31 ` [PATCH 2/2] i40evf: support interrupt based pf reset request Jingjing Wu
2016-01-27  1:49 ` [PATCH v2 0/2] " Jingjing Wu
2016-01-27  1:49   ` [PATCH v2 1/2] i40evf: allocate virtchnl cmd buffer for each vf Jingjing Wu
2016-01-29  7:28     ` Tao, Zhe
2016-02-14  2:22       ` Wu, Jingjing
2016-02-22  7:26     ` Zhang, Helin
2016-01-27  1:49   ` [PATCH v2 2/2] i40evf: support interrupt based pf reset request Jingjing Wu
2016-01-27  8:34     ` David Marchand
2016-02-14  3:25       ` Wu, Jingjing
2016-02-15 13:16         ` David Marchand
2016-02-18  4:06           ` Zhe Tao
2016-02-19  5:51           ` Wu, Jingjing
2016-01-28  7:03     ` Tao, Zhe
2016-02-14  2:12       ` Wu, Jingjing
2016-01-29  8:50     ` Tao, Zhe
2016-02-14  3:04       ` Wu, Jingjing
2016-02-22  8:26     ` Zhang, Helin
2016-02-26  6:51   ` [PATCH v3 0/2] i40evf: pf reset event report Jingjing Wu
2016-02-26  6:51     ` [PATCH v3 1/2] i40evf: allocate virtchnl cmd buffer for each vf Jingjing Wu
2016-02-26  8:12       ` Zhang, Helin
2016-02-26  6:51     ` [PATCH v3 2/2] i40evf: support to report pf reset event Jingjing Wu
2016-02-26  8:13       ` Zhang, Helin
2016-03-08 17:44     ` [PATCH v3 0/2] i40evf: pf reset event report Bruce Richardson
2016-03-09  3:08     ` Zhe Tao
2016-03-09  6:00     ` [PATCH v4 " Jingjing Wu
2016-03-09  6:00       ` Jingjing Wu [this message]
2016-03-09  6:00       ` [PATCH v4 2/2] i40evf: support to report pf reset event Jingjing Wu
2016-03-09  9:59         ` Thomas Monjalon
2016-03-09 11:01           ` Bruce Richardson
2016-03-09 11:26             ` expectations on maintainer's review Thomas Monjalon
2016-03-09 14:15               ` Bruce Richardson
2016-03-09 14:19                 ` Thomas Monjalon
2016-03-10  3:41       ` [PATCH v5 0/2] i40evf: pf reset event report Jingjing Wu
2016-03-10  3:41         ` [PATCH v5 1/2] i40evf: allocate virtchnl cmd buffer for each vf Jingjing Wu
2016-03-14 12:21           ` Bruce Richardson
2016-03-15  1:01             ` Wu, Jingjing
2016-03-10  3:41         ` [PATCH v5 2/2] i40evf: support to report pf reset event Jingjing Wu
2016-03-15  1:59         ` [PATCH v6 0/2] i40evf: pf reset event report Jingjing Wu
2016-03-15  1:59           ` [PATCH v6 1/2] i40evf: allocate virtchnl cmd buffer for each vf Jingjing Wu
2016-03-15  1:59           ` [PATCH v6 2/2] i40evf: support to report pf reset event Jingjing Wu
2016-03-22 15:13           ` [PATCH v6 0/2] i40evf: pf reset event report Bruce Richardson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1457503249-14878-2-git-send-email-jingjing.wu@intel.com \
    --to=jingjing.wu@intel.com \
    --cc=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.