summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernard Iremonger <bernard.iremonger@intel.com>2015-07-02 15:36:49 +0100
committerThomas Monjalon <thomas.monjalon@6wind.com>2015-07-19 21:22:14 +0200
commit2866c5f1b87e71badcaf4e9868c7e8a63e64eb5b (patch)
tree24b745cd52e63f2c97b790e8656a7252cf4ed146
parent54a385fa474e627a88beb16321c984a3b030c4dc (diff)
downloaddpdk-2866c5f1b87e71badcaf4e9868c7e8a63e64eb5b.zip
dpdk-2866c5f1b87e71badcaf4e9868c7e8a63e64eb5b.tar.gz
dpdk-2866c5f1b87e71badcaf4e9868c7e8a63e64eb5b.tar.xz
ixgbe: support port hotplug
This patch depends on the Port Hotplug Framework. It implements the eth_dev_uninit functions for rte_ixgbe_pmd and rte_ixgbevf_pmd. Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
-rw-r--r--drivers/net/ixgbe/ixgbe_ethdev.c98
-rw-r--r--drivers/net/ixgbe/ixgbe_ethdev.h2
-rw-r--r--drivers/net/ixgbe/ixgbe_pf.c22
3 files changed, 117 insertions, 5 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 19bcffe..ec470f6 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -129,6 +129,7 @@
| IXGBE_TIMINCA_INCVALUE)
static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev);
+static int eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev);
static int ixgbe_dev_configure(struct rte_eth_dev *dev);
static int ixgbe_dev_start(struct rte_eth_dev *dev);
static void ixgbe_dev_stop(struct rte_eth_dev *dev);
@@ -200,6 +201,7 @@ static void ixgbe_dcb_init(struct ixgbe_hw *hw,struct ixgbe_dcb_config *dcb_conf
/* For Virtual Function support */
static int eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev);
+static int eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev);
static int ixgbevf_dev_configure(struct rte_eth_dev *dev);
static int ixgbevf_dev_start(struct rte_eth_dev *dev);
static void ixgbevf_dev_stop(struct rte_eth_dev *dev);
@@ -1015,6 +1017,46 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
return 0;
}
+static int
+eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
+{
+ struct rte_pci_device *pci_dev;
+ struct ixgbe_hw *hw;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+ pci_dev = eth_dev->pci_dev;
+
+ if (hw->adapter_stopped == 0)
+ ixgbe_dev_close(eth_dev);
+
+ eth_dev->dev_ops = NULL;
+ eth_dev->rx_pkt_burst = NULL;
+ eth_dev->tx_pkt_burst = NULL;
+
+ /* Unlock any pending hardware semaphore */
+ ixgbe_swfw_lock_reset(hw);
+
+ /* disable uio intr before callback unregister */
+ rte_intr_disable(&(pci_dev->intr_handle));
+ rte_intr_callback_unregister(&(pci_dev->intr_handle),
+ ixgbe_dev_interrupt_handler, (void *)eth_dev);
+
+ /* uninitialize PF if max_vfs not zero */
+ ixgbe_pf_host_uninit(eth_dev);
+
+ rte_free(eth_dev->data->mac_addrs);
+ eth_dev->data->mac_addrs = NULL;
+
+ rte_free(eth_dev->data->hash_mac_addrs);
+ eth_dev->data->hash_mac_addrs = NULL;
+
+ return 0;
+}
/*
* Negotiate mailbox API version with the PF.
@@ -1188,13 +1230,58 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
return 0;
}
+/* Virtual Function device uninit */
+
+static int
+eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
+{
+ struct ixgbe_hw *hw;
+ unsigned i;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+
+ if (hw->adapter_stopped == 0)
+ ixgbevf_dev_close(eth_dev);
+
+ eth_dev->dev_ops = NULL;
+ eth_dev->rx_pkt_burst = NULL;
+ eth_dev->tx_pkt_burst = NULL;
+
+ /* Disable the interrupts for VF */
+ ixgbevf_intr_disable(hw);
+
+ for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+ ixgbe_dev_rx_queue_release(eth_dev->data->rx_queues[i]);
+ eth_dev->data->rx_queues[i] = NULL;
+ }
+ eth_dev->data->nb_rx_queues = 0;
+
+ for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+ ixgbe_dev_tx_queue_release(eth_dev->data->tx_queues[i]);
+ eth_dev->data->tx_queues[i] = NULL;
+ }
+ eth_dev->data->nb_tx_queues = 0;
+
+ rte_free(eth_dev->data->mac_addrs);
+ eth_dev->data->mac_addrs = NULL;
+
+ return 0;
+}
+
static struct eth_driver rte_ixgbe_pmd = {
.pci_drv = {
.name = "rte_ixgbe_pmd",
.id_table = pci_id_ixgbe_map,
- .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
+ RTE_PCI_DRV_DETACHABLE,
},
.eth_dev_init = eth_ixgbe_dev_init,
+ .eth_dev_uninit = eth_ixgbe_dev_uninit,
.dev_private_size = sizeof(struct ixgbe_adapter),
};
@@ -1205,9 +1292,10 @@ static struct eth_driver rte_ixgbevf_pmd = {
.pci_drv = {
.name = "rte_ixgbevf_pmd",
.id_table = pci_id_ixgbevf_map,
- .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
},
.eth_dev_init = eth_ixgbevf_dev_init,
+ .eth_dev_uninit = eth_ixgbevf_dev_uninit,
.dev_private_size = sizeof(struct ixgbe_adapter),
};
@@ -1577,7 +1665,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
}
/* stop adapter */
- hw->adapter_stopped = FALSE;
+ hw->adapter_stopped = 0;
ixgbe_stop_adapter(hw);
/* reinitialize adapter
@@ -1735,7 +1823,7 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
/* reset the NIC */
ixgbe_pf_reset_hw(hw);
- hw->adapter_stopped = FALSE;
+ hw->adapter_stopped = 0;
/* stop adapter */
ixgbe_stop_adapter(hw);
@@ -3224,7 +3312,7 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev)
PMD_INIT_FUNC_TRACE();
- hw->adapter_stopped = TRUE;
+ hw->adapter_stopped = 1;
ixgbe_stop_adapter(hw);
/*
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 755b674..a79d569 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -391,6 +391,8 @@ void ixgbe_vlan_hw_strip_disable_all(struct rte_eth_dev *dev);
void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev);
+void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev);
+
void ixgbe_pf_mbx_process(struct rte_eth_dev *eth_dev);
int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev);
diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index caed137..fd1c4ca 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -144,6 +144,28 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
return;
}
+void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev)
+{
+ struct ixgbe_vf_info **vfinfo;
+ uint16_t vf_num;
+
+ PMD_INIT_FUNC_TRACE();
+
+ vfinfo = IXGBE_DEV_PRIVATE_TO_P_VFDATA(eth_dev->data->dev_private);
+
+ RTE_ETH_DEV_SRIOV(eth_dev).active = 0;
+ RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool = 0;
+ RTE_ETH_DEV_SRIOV(eth_dev).def_vmdq_idx = 0;
+ RTE_ETH_DEV_SRIOV(eth_dev).def_pool_q_idx = 0;
+
+ vf_num = dev_num_vf(eth_dev);
+ if (vf_num == 0)
+ return;
+
+ rte_free(*vfinfo);
+ *vfinfo = NULL;
+}
+
int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
{
uint32_t vtctl, fcrth;