[dpdk-dev] [PATCH v2 2/2] i40evf: support interrupt based pf reset request

Zhang, Helin helin.zhang at intel.com
Mon Feb 22 09:26:53 CET 2016



> -----Original Message-----
> From: Wu, Jingjing
> Sent: Wednesday, January 27, 2016 9:50 AM
> To: dev at dpdk.org
> Cc: Wu, Jingjing; Zhang, Helin; Lu, Wenzhuo; Pei, Yulong
> Subject: [PATCH v2 2/2] i40evf: support interrupt based pf reset request
> 
> Interrupt based request of PF reset from PF is supported by enabling the
> adminq event process in VF driver.
> Users can register a callback for this interrupt event to get informed, when a
> PF reset request detected like:
>   rte_eth_dev_callback_register(portid,
> 		RTE_ETH_EVENT_INTR_RESET,
> 		reset_event_callback,
> 		arg);
> 
> Signed-off-by: Jingjing Wu <jingjing.wu at intel.com>
> ---
>  doc/guides/rel_notes/release_2_3.rst |   1 +
>  drivers/net/i40e/i40e_ethdev_vf.c    | 274
> +++++++++++++++++++++++++++++++----
>  lib/librte_ether/rte_ethdev.h        |   1 +
>  3 files changed, 246 insertions(+), 30 deletions(-)
> 
> diff --git a/doc/guides/rel_notes/release_2_3.rst
> b/doc/guides/rel_notes/release_2_3.rst
> index 99de186..73d5f76 100644
> --- a/doc/guides/rel_notes/release_2_3.rst
> +++ b/doc/guides/rel_notes/release_2_3.rst
> @@ -4,6 +4,7 @@ DPDK Release 2.3
>  New Features
>  ------------
> 
> +* **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 64e6957..1ffe64e 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]; @@ -
> 357,20 +358,42 @@ i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct
> vf_cmd_info *args)
>  		return err;
>  	}
> 
> -	do {
> -		/* Delay some time first */
> -		rte_delay_ms(ASQ_DELAY_MS);
> -		ret = i40evf_read_pfmsg(dev, &info);
> -		if (ret == I40EVF_MSG_CMD) {
> -			err = 0;
> -			break;
> -		} else if (ret == I40EVF_MSG_ERR) {
> -			err = -1;
> -			break;
> -		}
> -		/* 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 {
> +			/* Delay some time first */
> +			rte_delay_ms(ASQ_DELAY_MS);
> +			ret = i40evf_read_pfmsg(dev, &info);
> +			if (ret == I40EVF_MSG_CMD) {
> +				err = 0;
> +				break;
> +			} else if (ret == I40EVF_MSG_ERR) {
> +				err = -1;
> +				break;
> +			}
> +			/* 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 {
> +			/* Delay some time first */
> +			rte_delay_ms(ASQ_DELAY_MS);
> +			if (vf->pend_cmd ==
> I40E_VIRTCHNL_OP_UNKNOWN) {
> +				err = 0;
> +				break;
> +			}
> +			/* If don't read msg or read sys event, continue */
> +		} while (i++ < MAX_TRY_TIMES);
> +		break;
> +	}
> 
>  	return (err | vf->cmd_retval);
>  }
> @@ -719,7 +742,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; @@ -1093,6 +1116,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)
>  {
> @@ -1137,6 +1192,8 @@ i40evf_init_vf(struct rte_eth_dev *dev)
>  	int i, err, bufsz;
>  	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);
> +	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;
> @@ -1218,6 +1275,15 @@ i40evf_init_vf(struct rte_eth_dev *dev)
>  	ether_addr_copy((struct ether_addr *)vf->vsi_res-
> >default_mac_addr,
>  					(struct ether_addr *)hw->mac.addr);
> 
> +	/* 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));
> +	}
A write flush might be needed here?


More information about the dev mailing list