From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ferruh Yigit Subject: Re: [PATCH v2 02/32] net/i40e: add callback to user on VF to PF mbox msg Date: Wed, 7 Dec 2016 12:44:43 +0000 Message-ID: References: <1480637533-37425-1-git-send-email-wenzhuo.lu@intel.com> <1481081535-37448-1-git-send-email-wenzhuo.lu@intel.com> <1481081535-37448-3-git-send-email-wenzhuo.lu@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit To: Wenzhuo Lu , dev@dpdk.org Return-path: Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id BBF812B8F for ; Wed, 7 Dec 2016 13:44:46 +0100 (CET) In-Reply-To: <1481081535-37448-3-git-send-email-wenzhuo.lu@intel.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On 12/7/2016 3:31 AM, Wenzhuo Lu wrote: > The callback asks the user application if it is allowed to > perform the mailbox messages. > > If the return value from user is RTE_PMD_I40E_MB_EVENT_PROCEED > then continue. If ACK or NACK, do nothing and send > not_supported to VF. > > Signed-off-by: Wenzhuo Lu > --- > drivers/net/i40e/i40e_pf.c | 230 ++++++++++++++++++++++++++++++++++------ > drivers/net/i40e/rte_pmd_i40e.h | 21 ++++ > 2 files changed, 216 insertions(+), 35 deletions(-) > > diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c > index f70712b..8b8a14f 100644 > --- a/drivers/net/i40e/i40e_pf.c > +++ b/drivers/net/i40e/i40e_pf.c > @@ -55,6 +55,7 @@ > #include "i40e_ethdev.h" > #include "i40e_rxtx.h" > #include "i40e_pf.h" > +#include "rte_pmd_i40e.h" > > #define I40E_CFG_CRCSTRIP_DEFAULT 1 > > @@ -272,14 +273,23 @@ > } > > static void > -i40e_pf_host_process_cmd_version(struct i40e_pf_vf *vf) > +i40e_pf_host_process_cmd_version(struct i40e_pf_vf *vf, bool b_op) > { > struct i40e_virtchnl_version_info info; > > info.major = I40E_DPDK_VERSION_MAJOR; > info.minor = I40E_DPDK_VERSION_MINOR; > - i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_VERSION, > - I40E_SUCCESS, (uint8_t *)&info, sizeof(info)); > + > + if (b_op) > + i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_VERSION, > + I40E_SUCCESS, > + (uint8_t *)&info, > + sizeof(info)); > + else > + i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_VERSION, > + I40E_NOT_SUPPORTED, > + (uint8_t *)&info, > + sizeof(info)); Even I40E_NOT_SUPPORTED returned to the VF, it seems VF is ignoring this value, is it something should be fixed as part of this patch? This path is a little complex, I may be missing something but stack trace is: VF: i40evf_check_api_version() i40evf_execute_vf_cmd(vfd_cmd_info arg) i40e_aq_send_msg_to_pf(arg->op, retval, arg->in_msg) desc <- op, retval msg_in <- arg_in_msg i40e_asq_send_command(desc, msg_in) PF: i40e_pf_host_handle_vf_msg(op, msg_in) i40e_pf_host_process_cmd_version() i40e_pf_host_send_msg_to_vf(op, retval, msg_out) i40e_aq_send_msg_to_vf(op, retval, msg_out) desc <- op, retval i40e_asq_send_command(desc, msg_out) VF: data <- arg->out_xxx i40evf_read_pfmsg(data) event <- data->out_msg op <- retval <- i40e_clean_arq_element(event) event->desc <- desc event->msg <- msg_out data->result = retval <---------------- return 0; ver = arg->out_msg return 0; So, as far as I can see I40E_NOT_SUPPORTED is somewhere in the stack but not reached to the final VF function, is this OK? > } > > static int > @@ -292,13 +302,20 @@ > } > > static int > -i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf) > +i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf, bool b_op) > { > struct i40e_virtchnl_vf_resource *vf_res = NULL; > struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); > uint32_t len = 0; > int ret = I40E_SUCCESS; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf(vf, > + I40E_VIRTCHNL_OP_GET_VF_RESOURCES, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > /* only have 1 VSI by default */ > len = sizeof(struct i40e_virtchnl_vf_resource) + > I40E_DEFAULT_VF_VSI_NUM * > @@ -423,7 +440,8 @@ > static int > i40e_pf_host_process_cmd_config_vsi_queues(struct i40e_pf_vf *vf, > uint8_t *msg, > - uint16_t msglen) > + uint16_t msglen, > + bool b_op) > { > struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); > struct i40e_vsi *vsi = vf->vsi; > @@ -432,6 +450,13 @@ > struct i40e_virtchnl_queue_pair_info *vc_qpi; > int i, ret = I40E_SUCCESS; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf(vf, > + I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > if (!msg || vc_vqci->num_queue_pairs > vsi->nb_qps || > vc_vqci->num_queue_pairs > I40E_MAX_VSI_QP || > msglen < I40E_VIRTCHNL_CONFIG_VSI_QUEUES_SIZE(vc_vqci, > @@ -482,7 +507,8 @@ > static int > i40e_pf_host_process_cmd_config_vsi_queues_ext(struct i40e_pf_vf *vf, > uint8_t *msg, > - uint16_t msglen) > + uint16_t msglen, > + bool b_op) > { > struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); > struct i40e_vsi *vsi = vf->vsi; > @@ -491,6 +517,14 @@ > struct i40e_virtchnl_queue_pair_ext_info *vc_qpei; > int i, ret = I40E_SUCCESS; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf( > + vf, > + I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EXT, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > if (!msg || vc_vqcei->num_queue_pairs > vsi->nb_qps || > vc_vqcei->num_queue_pairs > I40E_MAX_VSI_QP || > msglen < I40E_VIRTCHNL_CONFIG_VSI_QUEUES_SIZE(vc_vqcei, > @@ -539,12 +573,21 @@ > > static int > i40e_pf_host_process_cmd_config_irq_map(struct i40e_pf_vf *vf, > - uint8_t *msg, uint16_t msglen) > + uint8_t *msg, uint16_t msglen, > + bool b_op) > { > int ret = I40E_SUCCESS; > struct i40e_virtchnl_irq_map_info *irqmap = > (struct i40e_virtchnl_irq_map_info *)msg; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf( > + vf, > + I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > if (msg == NULL || msglen < sizeof(struct i40e_virtchnl_irq_map_info)) { > PMD_DRV_LOG(ERR, "buffer too short"); > ret = I40E_ERR_PARAM; > @@ -646,12 +689,21 @@ > static int > i40e_pf_host_process_cmd_disable_queues(struct i40e_pf_vf *vf, > uint8_t *msg, > - uint16_t msglen) > + uint16_t msglen, > + bool b_op) > { > int ret = I40E_SUCCESS; > struct i40e_virtchnl_queue_select *q_sel = > (struct i40e_virtchnl_queue_select *)msg; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf( > + vf, > + I40E_VIRTCHNL_OP_DISABLE_QUEUES, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > if (msg == NULL || msglen != sizeof(*q_sel)) { > ret = I40E_ERR_PARAM; > goto send_msg; > @@ -669,7 +721,8 @@ > static int > i40e_pf_host_process_cmd_add_ether_address(struct i40e_pf_vf *vf, > uint8_t *msg, > - uint16_t msglen) > + uint16_t msglen, > + bool b_op) > { > int ret = I40E_SUCCESS; > struct i40e_virtchnl_ether_addr_list *addr_list = > @@ -678,6 +731,14 @@ > int i; > struct ether_addr *mac; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf( > + vf, > + I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > memset(&filter, 0 , sizeof(struct i40e_mac_filter_info)); > > if (msg == NULL || msglen <= sizeof(*addr_list)) { > @@ -707,7 +768,8 @@ > static int > i40e_pf_host_process_cmd_del_ether_address(struct i40e_pf_vf *vf, > uint8_t *msg, > - uint16_t msglen) > + uint16_t msglen, > + bool b_op) > { > int ret = I40E_SUCCESS; > struct i40e_virtchnl_ether_addr_list *addr_list = > @@ -715,6 +777,14 @@ > int i; > struct ether_addr *mac; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf( > + vf, > + I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > if (msg == NULL || msglen <= sizeof(*addr_list)) { > PMD_DRV_LOG(ERR, "delete_ether_address argument too short"); > ret = I40E_ERR_PARAM; > @@ -739,7 +809,8 @@ > > static int > i40e_pf_host_process_cmd_add_vlan(struct i40e_pf_vf *vf, > - uint8_t *msg, uint16_t msglen) > + uint8_t *msg, uint16_t msglen, > + bool b_op) > { > int ret = I40E_SUCCESS; > struct i40e_virtchnl_vlan_filter_list *vlan_filter_list = > @@ -747,6 +818,14 @@ > int i; > uint16_t *vid; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf( > + vf, > + I40E_VIRTCHNL_OP_ADD_VLAN, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > if (msg == NULL || msglen <= sizeof(*vlan_filter_list)) { > PMD_DRV_LOG(ERR, "add_vlan argument too short"); > ret = I40E_ERR_PARAM; > @@ -771,7 +850,8 @@ > static int > i40e_pf_host_process_cmd_del_vlan(struct i40e_pf_vf *vf, > uint8_t *msg, > - uint16_t msglen) > + uint16_t msglen, > + bool b_op) > { > int ret = I40E_SUCCESS; > struct i40e_virtchnl_vlan_filter_list *vlan_filter_list = > @@ -779,6 +859,14 @@ > int i; > uint16_t *vid; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf( > + vf, > + I40E_VIRTCHNL_OP_DEL_VLAN, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > if (msg == NULL || msglen <= sizeof(*vlan_filter_list)) { > PMD_DRV_LOG(ERR, "delete_vlan argument too short"); > ret = I40E_ERR_PARAM; > @@ -803,7 +891,8 @@ > i40e_pf_host_process_cmd_config_promisc_mode( > struct i40e_pf_vf *vf, > uint8_t *msg, > - uint16_t msglen) > + uint16_t msglen, > + bool b_op) > { > int ret = I40E_SUCCESS; > struct i40e_virtchnl_promisc_info *promisc = > @@ -811,6 +900,14 @@ > struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); > bool unicast = FALSE, multicast = FALSE; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf( > + vf, > + I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > if (msg == NULL || msglen != sizeof(*promisc)) { > ret = I40E_ERR_PARAM; > goto send_msg; > @@ -836,13 +933,20 @@ > } > > static int > -i40e_pf_host_process_cmd_get_stats(struct i40e_pf_vf *vf) > +i40e_pf_host_process_cmd_get_stats(struct i40e_pf_vf *vf, bool b_op) > { > i40e_update_vsi_stats(vf->vsi); > > - i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_STATS, > - I40E_SUCCESS, (uint8_t *)&vf->vsi->eth_stats, > - sizeof(vf->vsi->eth_stats)); > + if (b_op) > + i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_STATS, > + I40E_SUCCESS, > + (uint8_t *)&vf->vsi->eth_stats, > + sizeof(vf->vsi->eth_stats)); > + else > + i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_STATS, > + I40E_NOT_SUPPORTED, > + (uint8_t *)&vf->vsi->eth_stats, > + sizeof(vf->vsi->eth_stats)); > > return I40E_SUCCESS; > } > @@ -851,12 +955,21 @@ > i40e_pf_host_process_cmd_cfg_vlan_offload( > struct i40e_pf_vf *vf, > uint8_t *msg, > - uint16_t msglen) > + uint16_t msglen, > + bool b_op) > { > int ret = I40E_SUCCESS; > struct i40e_virtchnl_vlan_offload_info *offload = > (struct i40e_virtchnl_vlan_offload_info *)msg; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf( > + vf, > + I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > if (msg == NULL || msglen != sizeof(*offload)) { > ret = I40E_ERR_PARAM; > goto send_msg; > @@ -877,12 +990,21 @@ > static int > i40e_pf_host_process_cmd_cfg_pvid(struct i40e_pf_vf *vf, > uint8_t *msg, > - uint16_t msglen) > + uint16_t msglen, > + bool b_op) > { > int ret = I40E_SUCCESS; > struct i40e_virtchnl_pvid_info *tpid_info = > (struct i40e_virtchnl_pvid_info *)msg; > > + if (!b_op) { > + i40e_pf_host_send_msg_to_vf( > + vf, > + I40E_VIRTCHNL_OP_CFG_VLAN_PVID, > + I40E_NOT_SUPPORTED, NULL, 0); > + return ret; > + } > + > if (msg == NULL || msglen != sizeof(*tpid_info)) { > ret = I40E_ERR_PARAM; > goto send_msg; > @@ -923,6 +1045,8 @@ > struct i40e_pf_vf *vf; > /* AdminQ will pass absolute VF id, transfer to internal vf id */ > uint16_t vf_id = abs_vf_id - hw->func_caps.vf_base_id; > + struct rte_pmd_i40e_mb_event_param cb_param; > + bool b_op = TRUE; > > if (vf_id > pf->vf_num - 1 || !pf->vfs) { > PMD_DRV_LOG(ERR, "invalid argument"); > @@ -937,10 +1061,35 @@ > return; > } > > + /** > + * initialise structure to send to user application > + * will return response from user in retval field > + */ > + cb_param.retval = RTE_PMD_I40E_MB_EVENT_PROCEED; > + cb_param.vfid = vf_id; > + cb_param.msg_type = opcode; > + cb_param.msg = (void *)msg; > + cb_param.msglen = msglen; > + > + /** > + * Ask user application if we're allowed to perform those functions. > + * If we get cb_param.retval == RTE_PMD_I40E_MB_EVENT_PROCEED, > + * then business as usual. > + * If RTE_PMD_I40E_MB_EVENT_NOOP_ACK or RTE_PMD_I40E_MB_EVENT_NOOP_NACK, > + * do nothing and send not_supported to VF. As PF must send a response > + * to VF and ACK/NACK is not defined. > + */ > + _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX, &cb_param); > + if (cb_param.retval != RTE_PMD_I40E_MB_EVENT_PROCEED) { > + PMD_DRV_LOG(WARNING, "VF to PF message(%d) is not permitted!", > + opcode); > + b_op = FALSE; > + } > + Is the reason you just not do [1], because final function requires valid buffers? Can it be an option to fix them? [1] if (!b_op) { i40e_pf_host_send_msg_to_vf(vf, opcode, I40E_NOT_SUPPORTED, NULL, 0); } > switch (opcode) { > case I40E_VIRTCHNL_OP_VERSION : > PMD_DRV_LOG(INFO, "OP_VERSION received"); > - i40e_pf_host_process_cmd_version(vf); > + i40e_pf_host_process_cmd_version(vf, b_op); > break; > case I40E_VIRTCHNL_OP_RESET_VF : > PMD_DRV_LOG(INFO, "OP_RESET_VF received"); > @@ -948,61 +1097,72 @@ > break; > case I40E_VIRTCHNL_OP_GET_VF_RESOURCES: > PMD_DRV_LOG(INFO, "OP_GET_VF_RESOURCES received"); > - i40e_pf_host_process_cmd_get_vf_resource(vf); > + i40e_pf_host_process_cmd_get_vf_resource(vf, b_op); > break; > case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES: > PMD_DRV_LOG(INFO, "OP_CONFIG_VSI_QUEUES received"); > - i40e_pf_host_process_cmd_config_vsi_queues(vf, msg, msglen); > + i40e_pf_host_process_cmd_config_vsi_queues(vf, msg, > + msglen, b_op); > break; > case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EXT: > PMD_DRV_LOG(INFO, "OP_CONFIG_VSI_QUEUES_EXT received"); > i40e_pf_host_process_cmd_config_vsi_queues_ext(vf, msg, > - msglen); > + msglen, b_op); > break; > case I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP: > PMD_DRV_LOG(INFO, "OP_CONFIG_IRQ_MAP received"); > - i40e_pf_host_process_cmd_config_irq_map(vf, msg, msglen); > + i40e_pf_host_process_cmd_config_irq_map(vf, msg, msglen, b_op); > break; > case I40E_VIRTCHNL_OP_ENABLE_QUEUES: > PMD_DRV_LOG(INFO, "OP_ENABLE_QUEUES received"); > - i40e_pf_host_process_cmd_enable_queues(vf, msg, msglen); > - i40e_notify_vf_link_status(dev, vf); > + if (b_op) { > + i40e_pf_host_process_cmd_enable_queues(vf, msg, msglen); > + i40e_notify_vf_link_status(dev, vf); > + } else { > + i40e_pf_host_send_msg_to_vf( > + vf, I40E_VIRTCHNL_OP_ENABLE_QUEUES, > + I40E_NOT_SUPPORTED, NULL, 0); > + } > break; > case I40E_VIRTCHNL_OP_DISABLE_QUEUES: > PMD_DRV_LOG(INFO, "OP_DISABLE_QUEUE received"); > - i40e_pf_host_process_cmd_disable_queues(vf, msg, msglen); > + i40e_pf_host_process_cmd_disable_queues(vf, msg, msglen, b_op); > break; > case I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS: > PMD_DRV_LOG(INFO, "OP_ADD_ETHER_ADDRESS received"); > - i40e_pf_host_process_cmd_add_ether_address(vf, msg, msglen); > + i40e_pf_host_process_cmd_add_ether_address(vf, msg, > + msglen, b_op); > break; > case I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS: > PMD_DRV_LOG(INFO, "OP_DEL_ETHER_ADDRESS received"); > - i40e_pf_host_process_cmd_del_ether_address(vf, msg, msglen); > + i40e_pf_host_process_cmd_del_ether_address(vf, msg, > + msglen, b_op); > break; > case I40E_VIRTCHNL_OP_ADD_VLAN: > PMD_DRV_LOG(INFO, "OP_ADD_VLAN received"); > - i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen); > + i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen, b_op); > break; > case I40E_VIRTCHNL_OP_DEL_VLAN: > PMD_DRV_LOG(INFO, "OP_DEL_VLAN received"); > - i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen); > + i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen, b_op); > break; > case I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: > PMD_DRV_LOG(INFO, "OP_CONFIG_PROMISCUOUS_MODE received"); > - i40e_pf_host_process_cmd_config_promisc_mode(vf, msg, msglen); > + i40e_pf_host_process_cmd_config_promisc_mode(vf, msg, > + msglen, b_op); > break; > case I40E_VIRTCHNL_OP_GET_STATS: > PMD_DRV_LOG(INFO, "OP_GET_STATS received"); > - i40e_pf_host_process_cmd_get_stats(vf); > + i40e_pf_host_process_cmd_get_stats(vf, b_op); > break; > case I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD: > PMD_DRV_LOG(INFO, "OP_CFG_VLAN_OFFLOAD received"); > - i40e_pf_host_process_cmd_cfg_vlan_offload(vf, msg, msglen); > + i40e_pf_host_process_cmd_cfg_vlan_offload(vf, msg, > + msglen, b_op); > break; > case I40E_VIRTCHNL_OP_CFG_VLAN_PVID: > PMD_DRV_LOG(INFO, "OP_CFG_VLAN_PVID received"); > - i40e_pf_host_process_cmd_cfg_pvid(vf, msg, msglen); > + i40e_pf_host_process_cmd_cfg_pvid(vf, msg, msglen, b_op); > break; > /* Don't add command supported below, which will > * return an error code. > diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h > index 14852f2..eb7a72b 100644 > --- a/drivers/net/i40e/rte_pmd_i40e.h > +++ b/drivers/net/i40e/rte_pmd_i40e.h > @@ -42,6 +42,27 @@ > #include > > /** > + * Response sent back to i40e driver from user app after callback > + */ > +enum rte_pmd_i40e_mb_event_rsp { > + RTE_PMD_I40E_MB_EVENT_NOOP_ACK, /**< skip mbox request and ACK */ > + RTE_PMD_I40E_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */ > + RTE_PMD_I40E_MB_EVENT_PROCEED, /**< proceed with mbox request */ > + RTE_PMD_I40E_MB_EVENT_MAX /**< max value of this enum */ > +}; > + > +/** > + * Data sent to the user application when the callback is executed. > + */ > +struct rte_pmd_i40e_mb_event_param { > + uint16_t vfid; /**< Virtual Function number */ > + uint16_t msg_type; /**< VF to PF message type, see i40e_virtchnl_ops */ > + uint16_t retval; /**< return value */ > + void *msg; /**< pointer to message */ > + uint16_t msglen; /**< length of the message */ > +}; > + > +/** > * Notify VF when PF link status changes. > * > * @param port >