[dpdk-dev,v4,2/2] i40evf: support to report pf reset event

Message ID 1457503249-14878-3-git-send-email-jingjing.wu@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Bruce Richardson
Headers

Commit Message

Jingjing Wu March 9, 2016, 6 a.m. UTC
  When Linux PF and DPDK VF are used for i40e PMD, In case of PF reset,
interrupt will go via adminq event, VF need be informed the event,
a callback mechanism is introduced by VF. This will allow VF to
invoke callback when reset happens.
Users can register a callback for this interrupt event like:
  rte_eth_dev_callback_register(portid,
		RTE_ETH_EVENT_INTR_RESET,
		reset_event_callback,
		arg);

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |   2 +
 drivers/net/i40e/i40e_ethdev_vf.c      | 272 +++++++++++++++++++++++++++++----
 lib/librte_ether/rte_ethdev.h          |   1 +
 3 files changed, 246 insertions(+), 29 deletions(-)
  

Comments

Thomas Monjalon March 9, 2016, 9:59 a.m. UTC | #1
2016-03-09 14:00, Jingjing Wu:
> When Linux PF and DPDK VF are used for i40e PMD, In case of PF reset,
> interrupt will go via adminq event, VF need be informed the event,
> a callback mechanism is introduced by VF. This will allow VF to
> invoke callback when reset happens.
> Users can register a callback for this interrupt event like:
>   rte_eth_dev_callback_register(portid,
> 		RTE_ETH_EVENT_INTR_RESET,
> 		reset_event_callback,
> 		arg);
[...]
> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -105,6 +105,8 @@ This section should contain new features added in this release. Sample format:
>    be down.
>    We added the support of auto-neg by SW to avoid this link down issue.
>  
> +* **Added pf reset event reported in i40e vf PMD driver.

Bruce, is this comment clear enough for an user?

Beware of the wrong formating (missing **)
  
Bruce Richardson March 9, 2016, 11:01 a.m. UTC | #2
On Wed, Mar 09, 2016 at 10:59:56AM +0100, Thomas Monjalon wrote:
> 2016-03-09 14:00, Jingjing Wu:
> > When Linux PF and DPDK VF are used for i40e PMD, In case of PF reset,
> > interrupt will go via adminq event, VF need be informed the event,
> > a callback mechanism is introduced by VF. This will allow VF to
> > invoke callback when reset happens.
> > Users can register a callback for this interrupt event like:
> >   rte_eth_dev_callback_register(portid,
> > 		RTE_ETH_EVENT_INTR_RESET,
> > 		reset_event_callback,
> > 		arg);
> [...]
> > --- a/doc/guides/rel_notes/release_16_04.rst
> > +++ b/doc/guides/rel_notes/release_16_04.rst
> > @@ -105,6 +105,8 @@ This section should contain new features added in this release. Sample format:
> >    be down.
> >    We added the support of auto-neg by SW to avoid this link down issue.
> >  
> > +* **Added pf reset event reported in i40e vf PMD driver.
> 
> Bruce, is this comment clear enough for an user?
> 
> Beware of the wrong formating (missing **)

It's pretty ok, though I might word it a little differently myself. "reported"
should be "reporting".

Your question, though, does bring up the issue of scope and reviews again. I, as
committer, spend a lot of time tweaking commit messages, sanity checking
patches for compilation errors under various settings, and running checkpatch
etc. before applying them. However, IMHO it is up to the maintainers of the
various subsystems to enforce proper documentation in the patches submitted.
The maintainers are the primary gatekeepers here, and I, for one, don't want to
end up having to review all patches in detail before I apply them - otherwise
we'll be limited to a very small number of driver patches per release :)

In this case, if the submitter of the patch and the maintainer of the driver in
question are happy with the documentation, then who am I to go querying that. :-)

Having committers do full review on apply will only have two possible effects:
1. make the maintainers less conscientious about their job, since they know the
  committers will catch any real bugs or issues on apply
2. cause a lot of problems for submitters as they see a lot of issues being
  flagged at the last minute by committers, when they thought their patch was
  safely acked and ready for commit for some time.

We certainly see lots of the second issue occurring right now, I believe - [I'm
obvously not going to comment on the former :-)]

I'd be very much in favour of having a rule that once a patch is acked by a
maintainer, then it must be applied. We may suffer a bit from slightly lower
quality patches getting applied, but the speed of applying patches should
increase, and the patch contents can always be fixed by subsequent patches later.
[Unlike commit message which can't be fixed later without rewriting git history]
In this case, I feel that phrase "the perfect is the enemy of the good" applies.
https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good

Just my 2c on this. I'm sure you have a different view, Thomas, so it's probably
a discussion worth having.

/Bruce
  
Thomas Monjalon March 9, 2016, 11:26 a.m. UTC | #3
I've changed the title for this discussion.

2016-03-09 11:01, Bruce Richardson:
[snip comments about minor issue in release notes]

> Your question, though, does bring up the issue of scope and reviews again. I, as
> committer, spend a lot of time tweaking commit messages, sanity checking
> patches for compilation errors under various settings, and running checkpatch
> etc. before applying them. However, IMHO it is up to the maintainers of the
> various subsystems to enforce proper documentation in the patches submitted.
> The maintainers are the primary gatekeepers here, and I, for one, don't want to
> end up having to review all patches in detail before I apply them - otherwise
> we'll be limited to a very small number of driver patches per release :)

Yes that's a problem.

> In this case, if the submitter of the patch and the maintainer of the driver in
> question are happy with the documentation, then who am I to go querying that. :-)
> 
> Having committers do full review on apply will only have two possible effects:
> 1. make the maintainers less conscientious about their job, since they know the
>   committers will catch any real bugs or issues on apply

Yes we need maintainers to be conscientious on every parts of the patches.
One problem about the release notes and doc, is that not a lot of maintainers
have the "english skills".
Note that it would be easier if we would allow to write in Irish, Chinese or
French languages ;)
Unfortunately we took the constraints of writing in C and English.

> 2. cause a lot of problems for submitters as they see a lot of issues being
>   flagged at the last minute by committers, when they thought their patch was
>   safely acked and ready for commit for some time.
> 
> We certainly see lots of the second issue occurring right now, I believe - [I'm
> obvously not going to comment on the former :-)]
> 
> I'd be very much in favour of having a rule that once a patch is acked by a
> maintainer, then it must be applied. We may suffer a bit from slightly lower
> quality patches getting applied, but the speed of applying patches should
> increase, and the patch contents can always be fixed by subsequent patches later.
> [Unlike commit message which can't be fixed later without rewriting git history]
> In this case, I feel that phrase "the perfect is the enemy of the good" applies.
> https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good

Yes but I don't think saying we are OK to decrease the quality is a good message.
The reality is that people never rework what was been committed.
That's why we must be very careful on API and documentation.
About the release notes, decreasing its quality mean we don't care wether it is
read and understood. So maybe we can shrink it to less details and have only a
title with a git/author reference.

> Just my 2c on this. I'm sure you have a different view, Thomas, so it's probably
> a discussion worth having.

Thanks for bringing the discussion.
  
Bruce Richardson March 9, 2016, 2:15 p.m. UTC | #4
On Wed, Mar 09, 2016 at 12:26:58PM +0100, Thomas Monjalon wrote:
> I've changed the title for this discussion.
> 
> 2016-03-09 11:01, Bruce Richardson:
> [snip comments about minor issue in release notes]
> 
> > Your question, though, does bring up the issue of scope and reviews again. I, as
> > committer, spend a lot of time tweaking commit messages, sanity checking
> > patches for compilation errors under various settings, and running checkpatch
> > etc. before applying them. However, IMHO it is up to the maintainers of the
> > various subsystems to enforce proper documentation in the patches submitted.
> > The maintainers are the primary gatekeepers here, and I, for one, don't want to
> > end up having to review all patches in detail before I apply them - otherwise
> > we'll be limited to a very small number of driver patches per release :)
> 
> Yes that's a problem.
> 
> > In this case, if the submitter of the patch and the maintainer of the driver in
> > question are happy with the documentation, then who am I to go querying that. :-)
> > 
> > Having committers do full review on apply will only have two possible effects:
> > 1. make the maintainers less conscientious about their job, since they know the
> >   committers will catch any real bugs or issues on apply
> 
> Yes we need maintainers to be conscientious on every parts of the patches.

Definite +1

> One problem about the release notes and doc, is that not a lot of maintainers
> have the "english skills".
> Note that it would be easier if we would allow to write in Irish, Chinese or
> French languages ;)
> Unfortunately we took the constraints of writing in C and English.
> 

Yes, language is a good point, and I'm ok with helping to clean up grammar and 
minor language issues e.g. the one word correction I suggested at the start of
this discussion. For the scope of the text, and whether it contains enough
information, I would tend to push that responsibility back on the maintainer
though.


> > 2. cause a lot of problems for submitters as they see a lot of issues being
> >   flagged at the last minute by committers, when they thought their patch was
> >   safely acked and ready for commit for some time.
> > 
> > We certainly see lots of the second issue occurring right now, I believe - [I'm
> > obvously not going to comment on the former :-)]
> > 
> > I'd be very much in favour of having a rule that once a patch is acked by a
> > maintainer, then it must be applied. We may suffer a bit from slightly lower
> > quality patches getting applied, but the speed of applying patches should
> > increase, and the patch contents can always be fixed by subsequent patches later.
> > [Unlike commit message which can't be fixed later without rewriting git history]
> > In this case, I feel that phrase "the perfect is the enemy of the good" applies.
> > https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good
> 
> Yes but I don't think saying we are OK to decrease the quality is a good message.
> The reality is that people never rework what was been committed.

Yes, point taken.

> That's why we must be very careful on API and documentation.
> About the release notes, decreasing its quality mean we don't care wether it is
> read and understood. So maybe we can shrink it to less details and have only a
> title with a git/author reference.

I don't think I agree with that. I think the doc should be readable independently
of having the git repo.

> 
> > Just my 2c on this. I'm sure you have a different view, Thomas, so it's probably
> > a discussion worth having.
> 
> Thanks for bringing the discussion.

Indeed. So I would summarise this as:
* an ask to the maintainers to pay increased attention to documentation side of
patches when reviewing and acking.
* on my end, I will do some doc reviews as part of applying commits, but on a
best-effort basis. The primary responsibility is with the maintainers to ensure
documentation quantity before patch application stage.

Does that seem reasonable?

Regards,
/Bruce
  
Thomas Monjalon March 9, 2016, 2:19 p.m. UTC | #5
2016-03-09 14:15, Bruce Richardson:
> On Wed, Mar 09, 2016 at 12:26:58PM +0100, Thomas Monjalon wrote:
> > I've changed the title for this discussion.
> > 
> > 2016-03-09 11:01, Bruce Richardson:
> > [snip comments about minor issue in release notes]
> > 
> > > Your question, though, does bring up the issue of scope and reviews again. I, as
> > > committer, spend a lot of time tweaking commit messages, sanity checking
> > > patches for compilation errors under various settings, and running checkpatch
> > > etc. before applying them. However, IMHO it is up to the maintainers of the
> > > various subsystems to enforce proper documentation in the patches submitted.
> > > The maintainers are the primary gatekeepers here, and I, for one, don't want to
> > > end up having to review all patches in detail before I apply them - otherwise
> > > we'll be limited to a very small number of driver patches per release :)
> > 
> > Yes that's a problem.
> > 
> > > In this case, if the submitter of the patch and the maintainer of the driver in
> > > question are happy with the documentation, then who am I to go querying that. :-)
> > > 
> > > Having committers do full review on apply will only have two possible effects:
> > > 1. make the maintainers less conscientious about their job, since they know the
> > >   committers will catch any real bugs or issues on apply
> > 
> > Yes we need maintainers to be conscientious on every parts of the patches.
> 
> Definite +1
> 
> > One problem about the release notes and doc, is that not a lot of maintainers
> > have the "english skills".
> > Note that it would be easier if we would allow to write in Irish, Chinese or
> > French languages ;)
> > Unfortunately we took the constraints of writing in C and English.
> > 
> 
> Yes, language is a good point, and I'm ok with helping to clean up grammar and 
> minor language issues e.g. the one word correction I suggested at the start of
> this discussion. For the scope of the text, and whether it contains enough
> information, I would tend to push that responsibility back on the maintainer
> though.
> 
> 
> > > 2. cause a lot of problems for submitters as they see a lot of issues being
> > >   flagged at the last minute by committers, when they thought their patch was
> > >   safely acked and ready for commit for some time.
> > > 
> > > We certainly see lots of the second issue occurring right now, I believe - [I'm
> > > obvously not going to comment on the former :-)]
> > > 
> > > I'd be very much in favour of having a rule that once a patch is acked by a
> > > maintainer, then it must be applied. We may suffer a bit from slightly lower
> > > quality patches getting applied, but the speed of applying patches should
> > > increase, and the patch contents can always be fixed by subsequent patches later.
> > > [Unlike commit message which can't be fixed later without rewriting git history]
> > > In this case, I feel that phrase "the perfect is the enemy of the good" applies.
> > > https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good
> > 
> > Yes but I don't think saying we are OK to decrease the quality is a good message.
> > The reality is that people never rework what was been committed.
> 
> Yes, point taken.
> 
> > That's why we must be very careful on API and documentation.
> > About the release notes, decreasing its quality mean we don't care wether it is
> > read and understood. So maybe we can shrink it to less details and have only a
> > title with a git/author reference.
> 
> I don't think I agree with that. I think the doc should be readable independently
> of having the git repo.
> 
> > 
> > > Just my 2c on this. I'm sure you have a different view, Thomas, so it's probably
> > > a discussion worth having.
> > 
> > Thanks for bringing the discussion.
> 
> Indeed. So I would summarise this as:
> * an ask to the maintainers to pay increased attention to documentation side of
> patches when reviewing and acking.
> * on my end, I will do some doc reviews as part of applying commits, but on a
> best-effort basis. The primary responsibility is with the maintainers to ensure
> documentation quantity before patch application stage.
> 
> Does that seem reasonable?

Yes and I'd like to hear some maintainers to comment or commit this summary.
  

Patch

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index eab5f92..a872d40 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -105,6 +105,8 @@  This section should contain new features added in this release. Sample format:
   be down.
   We added the support of auto-neg by SW to avoid this link down issue.
 
+* **Added pf reset event reported in i40e vf PMD driver.
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 90edeb5..ede4bc2 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -74,8 +74,6 @@ 
 #define I40EVF_BUSY_WAIT_DELAY 10
 #define I40EVF_BUSY_WAIT_COUNT 50
 #define MAX_RESET_WAIT_CNT     20
-/*ITR index for NOITR*/
-#define I40E_QINT_RQCTL_MSIX_INDX_NOITR     3
 
 struct i40evf_arq_msg_info {
 	enum i40e_virtchnl_ops ops;
@@ -151,6 +149,9 @@  static int
 i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
 static int
 i40evf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);
+static void i40evf_handle_pf_event(__rte_unused struct rte_eth_dev *dev,
+			   uint8_t *msg,
+			   uint16_t msglen);
 
 /* Default hash key buffer for RSS */
 static uint32_t rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1];
@@ -335,19 +336,40 @@  i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args)
 		return err;
 	}
 
-	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);
+	switch (args->ops) {
+	case I40E_VIRTCHNL_OP_RESET_VF:
+		/*no need to process in this function */
+		break;
+	case I40E_VIRTCHNL_OP_VERSION:
+	case I40E_VIRTCHNL_OP_GET_VF_RESOURCES:
+		/* for init adminq commands, need to poll the response */
+		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);
+		break;
+
+	default:
+		/* for other adminq in running time, waiting the cmd done flag */
+		do {
+			if (vf->pend_cmd == I40E_VIRTCHNL_OP_UNKNOWN) {
+				err = 0;
+				break;
+			}
+			rte_delay_ms(ASQ_DELAY_MS);
+			/* If don't read msg or read sys event, continue */
+		} while (i++ < MAX_TRY_TIMES);
+		break;
+	}
 
 	return err | vf->cmd_retval;
 }
@@ -696,7 +718,7 @@  i40evf_config_irq_map(struct rte_eth_dev *dev)
 
 	map_info = (struct i40e_virtchnl_irq_map_info *)cmd_buffer;
 	map_info->num_vectors = 1;
-	map_info->vecmap[0].rxitr_idx = I40E_QINT_RQCTL_MSIX_INDX_NOITR;
+	map_info->vecmap[0].rxitr_idx = I40E_ITR_INDEX_DEFAULT;
 	map_info->vecmap[0].vsi_id = vf->vsi_res->vsi_id;
 	/* Alway use default dynamic MSIX interrupt */
 	map_info->vecmap[0].vector_id = vector_id;
@@ -1070,6 +1092,38 @@  i40evf_dev_atomic_write_link_status(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* Disable IRQ0 */
+static inline void
+i40evf_disable_irq0(struct i40e_hw *hw)
+{
+	/* Disable all interrupt types */
+	I40E_WRITE_REG(hw, I40E_VFINT_ICR0_ENA1, 0);
+	I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01,
+		       I40E_VFINT_DYN_CTL01_ITR_INDX_MASK);
+	I40EVF_WRITE_FLUSH(hw);
+}
+
+/* Enable IRQ0 */
+static inline void
+i40evf_enable_irq0(struct i40e_hw *hw)
+{
+	/* Enable admin queue interrupt trigger */
+	uint32_t val;
+
+	i40evf_disable_irq0(hw);
+	val = I40E_READ_REG(hw, I40E_VFINT_ICR0_ENA1);
+	val |= I40E_VFINT_ICR0_ENA1_ADMINQ_MASK |
+		I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_MASK;
+	I40E_WRITE_REG(hw, I40E_VFINT_ICR0_ENA1, val);
+
+	I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01,
+		I40E_VFINT_DYN_CTL01_INTENA_MASK |
+		I40E_VFINT_DYN_CTL01_CLEARPBA_MASK |
+		I40E_VFINT_DYN_CTL01_ITR_INDX_MASK);
+
+	I40EVF_WRITE_FLUSH(hw);
+}
+
 static int
 i40evf_reset_vf(struct i40e_hw *hw)
 {
@@ -1115,6 +1169,8 @@  i40evf_init_vf(struct rte_eth_dev *dev)
 	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 ether_addr *p_mac_addr;
+	uint16_t interval =
+		i40e_calc_itr_interval(I40E_QUEUE_ITR_INTERVAL_MAX);
 
 	vf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	vf->dev_data = dev->data;
@@ -1195,6 +1251,16 @@  i40evf_init_vf(struct rte_eth_dev *dev)
 	else
 		eth_random_addr(hw->mac.addr); /* Generate a random one */
 
+	/* If the PF host is not DPDK, set the interval of ITR0 to max*/
+	if (vf->version_major != I40E_DPDK_VERSION_MAJOR) {
+		I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01,
+			       (I40E_ITR_INDEX_DEFAULT <<
+				I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT) |
+			       (interval <<
+				I40E_VFINT_DYN_CTL0_INTERVAL_SHIFT));
+		I40EVF_WRITE_FLUSH(hw);
+	}
+
 	return 0;
 
 err_alloc:
@@ -1223,11 +1289,142 @@  i40evf_uninit_vf(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static void
+i40evf_handle_pf_event(__rte_unused struct rte_eth_dev *dev,
+			   uint8_t *msg,
+			   __rte_unused uint16_t msglen)
+{
+	struct i40e_virtchnl_pf_event *pf_msg =
+			(struct i40e_virtchnl_pf_event *)msg;
+
+	switch (pf_msg->event) {
+	case I40E_VIRTCHNL_EVENT_RESET_IMPENDING:
+		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event\n");
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+		break;
+	case I40E_VIRTCHNL_EVENT_LINK_CHANGE:
+		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event\n");
+		break;
+	case I40E_VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
+		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_PF_DRIVER_CLOSE event\n");
+		break;
+	default:
+		PMD_DRV_LOG(ERR, " unknown event received %u", pf_msg->event);
+		break;
+	}
+}
+
+static void
+i40evf_handle_aq_msg(struct rte_eth_dev *dev)
+{
+	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 info;
+	struct i40e_virtchnl_msg *v_msg;
+	uint16_t pending, opcode;
+	int ret;
+
+	info.buf_len = I40E_AQ_BUF_SZ;
+	if (!vf->aq_resp) {
+		PMD_DRV_LOG(ERR, "Buffer for adminq resp should not be NULL");
+		return;
+	}
+	info.msg_buf = vf->aq_resp;
+	v_msg = (struct i40e_virtchnl_msg *)&info.desc;
+
+	pending = 1;
+	while (pending) {
+		ret = i40e_clean_arq_element(hw, &info, &pending);
+
+		if (ret != I40E_SUCCESS) {
+			PMD_DRV_LOG(INFO, "Failed to read msg from AdminQ,"
+				    "ret: %d", ret);
+			break;
+		}
+		opcode = rte_le_to_cpu_16(info.desc.opcode);
+
+		switch (opcode) {
+		case i40e_aqc_opc_send_msg_to_vf:
+			if (v_msg->v_opcode == I40E_VIRTCHNL_OP_EVENT)
+				/* process event*/
+				i40evf_handle_pf_event(dev, info.msg_buf,
+							info.msg_len);
+			else {
+				/* read message and it's expected one */
+				if (v_msg->v_opcode == vf->pend_cmd) {
+					vf->cmd_retval = v_msg->v_retval;
+					/* prevent compiler reordering */
+					rte_compiler_barrier();
+					_clear_cmd(vf);
+				} else
+					PMD_DRV_LOG(ERR, "command mismatch,"
+						"expect %u, get %u",
+						vf->pend_cmd, v_msg->v_opcode);
+				PMD_DRV_LOG(DEBUG, "adminq response is received,"
+					     " opcode = %d\n", v_msg->v_opcode);
+			}
+			break;
+		default:
+			PMD_DRV_LOG(ERR, "Request %u is not supported yet",
+				    opcode);
+			break;
+		}
+	}
+}
+
+/**
+ * Interrupt handler triggered by NIC  for handling
+ * specific interrupt. Only adminq interrupt is processed in VF.
+ *
+ * @param handle
+ *  Pointer to interrupt handle.
+ * @param param
+ *  The address of parameter (struct rte_eth_dev *) regsitered before.
+ *
+ * @return
+ *  void
+ */
+static void
+i40evf_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
+			   void *param)
+{
+	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t icr0;
+
+	i40evf_disable_irq0(hw);
+
+	/* read out interrupt causes */
+	icr0 = I40E_READ_REG(hw, I40E_VFINT_ICR01);
+
+	/* No interrupt event indicated */
+	if (!(icr0 & I40E_VFINT_ICR01_INTEVENT_MASK)) {
+		PMD_DRV_LOG(DEBUG, "No interrupt event, nothing to do\n");
+		goto done;
+	}
+
+	if (icr0 & I40E_VFINT_ICR01_ADMINQ_MASK) {
+		PMD_DRV_LOG(DEBUG, "ICR01_ADMINQ is reported\n");
+		i40evf_handle_aq_msg(dev);
+	}
+
+	/* Link Status Change interrupt */
+	if (icr0 & I40E_VFINT_ICR01_LINK_STAT_CHANGE_MASK)
+		PMD_DRV_LOG(DEBUG, "LINK_STAT_CHANGE is reported,"
+				   " do nothing\n");
+
+done:
+	i40evf_enable_irq0(hw);
+	rte_intr_enable(&(dev->pci_dev->intr_handle));
+}
+
+
 static int
 i40evf_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(\
 			eth_dev->data->dev_private);
+	struct rte_pci_device *pci_dev = eth_dev->pci_dev;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1262,6 +1459,16 @@  i40evf_dev_init(struct rte_eth_dev *eth_dev)
 		return -1;
 	}
 
+	/* register callback func to eal lib */
+	rte_intr_callback_register(&(pci_dev->intr_handle),
+		i40evf_dev_interrupt_handler, (void *)eth_dev);
+
+	/* enable uio intr after callback register */
+	rte_intr_enable(&(pci_dev->intr_handle));
+
+	/* configure and enable device interrupt */
+	i40evf_enable_irq0(hw);
+
 	/* copy mac addr */
 	eth_dev->data->mac_addrs = rte_zmalloc("i40evf_mac",
 					ETHER_ADDR_LEN, 0);
@@ -1639,7 +1846,8 @@  i40evf_enable_queues_intr(struct rte_eth_dev *dev)
 		I40E_WRITE_REG(hw,
 			       I40E_VFINT_DYN_CTL01,
 			       I40E_VFINT_DYN_CTL01_INTENA_MASK |
-			       I40E_VFINT_DYN_CTL01_CLEARPBA_MASK);
+			       I40E_VFINT_DYN_CTL01_CLEARPBA_MASK |
+			       I40E_VFINT_DYN_CTL01_ITR_INDX_MASK);
 		I40EVF_WRITE_FLUSH(hw);
 		return;
 	}
@@ -1650,11 +1858,10 @@  i40evf_enable_queues_intr(struct rte_eth_dev *dev)
 			I40E_VFINT_DYN_CTLN1(I40EVF_VSI_DEFAULT_MSIX_INTR - 1),
 			I40E_VFINT_DYN_CTLN1_INTENA_MASK |
 			I40E_VFINT_DYN_CTLN_CLEARPBA_MASK);
-	else
-		/* To support Linux PF host */
-		I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01,
-				I40E_VFINT_DYN_CTL01_INTENA_MASK |
-				I40E_VFINT_DYN_CTL01_CLEARPBA_MASK);
+	/* If host driver is kernel driver, do nothing.
+	 * Interrupt 0 is used for rx packets, but don't set I40E_VFINT_DYN_CTL01,
+	 * because it is already done in i40evf_enable_irq0.
+	 */
 
 	I40EVF_WRITE_FLUSH(hw);
 }
@@ -1667,7 +1874,8 @@  i40evf_disable_queues_intr(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 
 	if (!rte_intr_allow_others(intr_handle)) {
-		I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01, 0);
+		I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01,
+			       I40E_VFINT_DYN_CTL01_ITR_INDX_MASK);
 		I40EVF_WRITE_FLUSH(hw);
 		return;
 	}
@@ -1677,8 +1885,10 @@  i40evf_disable_queues_intr(struct rte_eth_dev *dev)
 			       I40E_VFINT_DYN_CTLN1(I40EVF_VSI_DEFAULT_MSIX_INTR
 						    - 1),
 			       0);
-	else
-		I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01, 0);
+	/* If host driver is kernel driver, do nothing.
+	 * Interrupt 0 is used for rx packets, but don't zero I40E_VFINT_DYN_CTL01,
+	 * because interrupt 0 is also used for adminq processing.
+	 */
 
 	I40EVF_WRITE_FLUSH(hw);
 }
@@ -1802,10 +2012,6 @@  i40evf_dev_start(struct rte_eth_dev *dev)
 		goto err_mac;
 	}
 
-	/* vf don't allow intr except for rxq intr */
-	if (dev->data->dev_conf.intr_conf.rxq != 0)
-		rte_intr_enable(intr_handle);
-
 	i40evf_enable_queues_intr(dev);
 	return 0;
 
@@ -1997,12 +2203,20 @@  static void
 i40evf_dev_close(struct rte_eth_dev *dev)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_pci_device *pci_dev = dev->pci_dev;
 
 	i40evf_dev_stop(dev);
 	hw->adapter_stopped = 1;
 	i40e_dev_free_queues(dev);
 	i40evf_reset_vf(hw);
 	i40e_shutdown_adminq(hw);
+	/* disable uio intr before callback unregister */
+	rte_intr_disable(&(pci_dev->intr_handle));
+
+	/* unregister callback func from eal lib */
+	rte_intr_callback_unregister(&(pci_dev->intr_handle),
+		i40evf_dev_interrupt_handler, (void *)dev);
+	i40evf_disable_irq0(hw);
 }
 
 static int
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e2893ba..0c81435 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -2663,6 +2663,7 @@  rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,
 enum rte_eth_event_type {
 	RTE_ETH_EVENT_UNKNOWN,  /**< unknown event type */
 	RTE_ETH_EVENT_INTR_LSC, /**< lsc interrupt event */
+	RTE_ETH_EVENT_INTR_RESET, /**< reset interrupt event */
 	RTE_ETH_EVENT_MAX       /**< max value of this enum */
 };