From: Cunming Liang Date: Wed, 4 Nov 2015 08:45:38 +0000 (+0800) Subject: igb: fix VF start with PF stopped X-Git-Tag: spdx-start~8125 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=fe685de2b1b6;p=dpdk.git igb: fix VF start with PF stopped When igb runs as a PF, mbox interrupt is prerequisite to make VF start normally. And PF sometimes won't 'dev_start', so the mbox interrupt register during 'dev_init' is required. The patch rolls back the interrupt register for mbox,lsc to the 'dev_init'. As UIO doesn't support multiple vector, mbox has to occupy the only one. It adds condition check on 'dev_start', rxq interrupt is not allowed when PF running in IOV mode via UIO. Signed-off-by: Cunming Liang --- diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst index 0c7abe995a..4ad9287591 100644 --- a/doc/guides/rel_notes/release_2_2.rst +++ b/doc/guides/rel_notes/release_2_2.rst @@ -114,6 +114,10 @@ Drivers in Intel I210 NIC, as EtherType in RX descriptor is in bits 8:10 of Packet Type and not in the default bits 0:2. +* **igb: Fixed VF start with PF stopped.** + + VF needs the PF interrupt support initialized even if not started. + * **ixgbe: Fixed issue with X550 DCB.** Fixed a DCB issue with x550 where for 8 TCs (Traffic Classes), if a packet diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index 76d2acc79a..2cb115cd06 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -760,6 +760,13 @@ eth_igb_dev_init(struct rte_eth_dev *eth_dev) eth_dev->data->port_id, pci_dev->id.vendor_id, pci_dev->id.device_id); + rte_intr_callback_register(&pci_dev->intr_handle, + eth_igb_interrupt_handler, + (void *)eth_dev); + + /* enable uio/vfio intr/eventfd mapping */ + rte_intr_enable(&pci_dev->intr_handle); + /* enable support intr */ igb_intr_enable(eth_dev); @@ -1122,13 +1129,15 @@ eth_igb_start(struct rte_eth_dev *dev) igb_pf_host_configure(dev); /* check and configure queue intr-vector mapping */ - if (dev->data->dev_conf.intr_conf.rxq != 0) { + if ((rte_intr_cap_multiple(intr_handle) || + !RTE_ETH_DEV_SRIOV(dev).active) && + dev->data->dev_conf.intr_conf.rxq != 0) { intr_vector = dev->data->nb_rx_queues; if (rte_intr_efd_enable(intr_handle, intr_vector)) return -1; } - if (rte_intr_dp_is_en(intr_handle)) { + if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) { intr_handle->intr_vec = rte_zmalloc("intr_vec", dev->data->nb_rx_queues * sizeof(int), 0); @@ -1221,20 +1230,22 @@ eth_igb_start(struct rte_eth_dev *dev) } e1000_setup_link(hw); - /* check if lsc interrupt feature is enabled */ - if (dev->data->dev_conf.intr_conf.lsc != 0) { - if (rte_intr_allow_others(intr_handle)) { - rte_intr_callback_register(intr_handle, - eth_igb_interrupt_handler, - (void *)dev); + if (rte_intr_allow_others(intr_handle)) { + /* check if lsc interrupt is enabled */ + if (dev->data->dev_conf.intr_conf.lsc != 0) eth_igb_lsc_interrupt_setup(dev); - } else + } else { + rte_intr_callback_unregister(intr_handle, + eth_igb_interrupt_handler, + (void *)dev); + if (dev->data->dev_conf.intr_conf.lsc != 0) PMD_INIT_LOG(INFO, "lsc won't enable because of" " no intr multiplex\n"); } /* check if rxq interrupt is enabled */ - if (dev->data->dev_conf.intr_conf.rxq != 0) + if (dev->data->dev_conf.intr_conf.rxq != 0 && + rte_intr_dp_is_en(intr_handle)) eth_igb_rxq_interrupt_setup(dev); /* enable uio/vfio intr/eventfd mapping */ @@ -1327,6 +1338,12 @@ eth_igb_stop(struct rte_eth_dev *dev) } filter_info->twotuple_mask = 0; + if (!rte_intr_allow_others(intr_handle)) + /* resume to the default handler */ + rte_intr_callback_register(intr_handle, + eth_igb_interrupt_handler, + (void *)dev); + /* Clean datapath event and queue/vec mapping */ rte_intr_efd_disable(intr_handle); if (intr_handle->intr_vec != NULL) {