From patchwork Wed May 6 11:20:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iremonger, Bernard" X-Patchwork-Id: 4637 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 3C89C1396; Wed, 6 May 2015 13:20:38 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 68C9812A8 for ; Wed, 6 May 2015 13:20:36 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP; 06 May 2015 04:20:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,379,1427785200"; d="scan'208";a="690735082" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga001.jf.intel.com with ESMTP; 06 May 2015 04:20:34 -0700 Received: from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com [10.237.217.45]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id t46BKX10010033; Wed, 6 May 2015 12:20:33 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id t46BKXc2008782; Wed, 6 May 2015 12:20:33 +0100 Received: (from bairemon@localhost) by sivswdev01.ir.intel.com with id t46BKX7K008778; Wed, 6 May 2015 12:20:33 +0100 From: Bernard Iremonger To: dev@dpdk.org Date: Wed, 6 May 2015 12:20:31 +0100 Message-Id: <1430911231-8744-1-git-send-email-bernard.iremonger@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: References: Subject: [dpdk-dev] [RFC PATCH V2] librte_pmd_e1000: igb and em1000 PCI Port Hotplug changes X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch depends on the Port Hotplug Framework. It implements the eth_dev_uninit functions for rte_em_pmd, rte_igb_pmd and rte_igbvf_pmd. Changes in V2: Call dev_close() from dev_uninit() functions. Remove input parameter checking from dev_unit() functions. Signed-off-by: Bernard Iremonger --- lib/librte_pmd_e1000/e1000/e1000_hw.h | 3 +- lib/librte_pmd_e1000/e1000_ethdev.h | 4 +- lib/librte_pmd_e1000/em_ethdev.c | 42 +++++++++++++++++- lib/librte_pmd_e1000/igb_ethdev.c | 79 +++++++++++++++++++++++++++++++- lib/librte_pmd_e1000/igb_pf.c | 24 ++++++++++- 5 files changed, 144 insertions(+), 8 deletions(-) diff --git a/lib/librte_pmd_e1000/e1000/e1000_hw.h b/lib/librte_pmd_e1000/e1000/e1000_hw.h index 4dd92a3..60cd237 100644 --- a/lib/librte_pmd_e1000/e1000/e1000_hw.h +++ b/lib/librte_pmd_e1000/e1000/e1000_hw.h @@ -1,6 +1,6 @@ /******************************************************************************* -Copyright (c) 2001-2014, Intel Corporation +Copyright (c) 2001-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -1005,6 +1005,7 @@ struct e1000_hw { u16 vendor_id; u8 revision_id; + bool adapter_stopped; }; #include "e1000_82541.h" diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h index c451faa..51720b9 100644 --- a/lib/librte_pmd_e1000/e1000_ethdev.h +++ b/lib/librte_pmd_e1000/e1000_ethdev.h @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -298,6 +298,8 @@ void eth_igbvf_tx_init(struct rte_eth_dev *dev); */ void igb_pf_host_init(struct rte_eth_dev *eth_dev); +void igb_pf_host_uninit(struct rte_eth_dev *eth_dev); + void igb_pf_mbx_process(struct rte_eth_dev *eth_dev); int igb_pf_host_configure(struct rte_eth_dev *eth_dev); diff --git a/lib/librte_pmd_e1000/em_ethdev.c b/lib/librte_pmd_e1000/em_ethdev.c index da02988..fa94ee6 100644 --- a/lib/librte_pmd_e1000/em_ethdev.c +++ b/lib/librte_pmd_e1000/em_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -241,6 +241,7 @@ eth_em_dev_init(struct rte_eth_dev *eth_dev) hw->hw_addr = (void *)pci_dev->mem_resource[0].addr; hw->device_id = pci_dev->id.device_id; + hw->adapter_stopped = FALSE; /* For ICH8 support we'll need to map the flash memory BAR */ @@ -280,13 +281,47 @@ eth_em_dev_init(struct rte_eth_dev *eth_dev) return (0); } +static int +eth_em_dev_uninit(struct rte_eth_dev *eth_dev) +{ + struct rte_pci_device *pci_dev; + struct e1000_hw *hw; + + PMD_INIT_FUNC_TRACE(); + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return -EPERM; + + pci_dev = eth_dev->pci_dev; + hw = E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + + if (hw->adapter_stopped == FALSE) + eth_em_close(eth_dev); + + eth_dev->dev_ops = NULL; + eth_dev->rx_pkt_burst = NULL; + eth_dev->tx_pkt_burst = NULL; + + rte_free(eth_dev->data->mac_addrs); + eth_dev->data->mac_addrs = NULL; + + /* disable uio intr before callback unregister */ + rte_intr_disable(&(pci_dev->intr_handle)); + rte_intr_callback_unregister(&(pci_dev->intr_handle), + eth_em_interrupt_handler, (void *)eth_dev); + + return 0; +} + static struct eth_driver rte_em_pmd = { { .name = "rte_em_pmd", .id_table = pci_id_em_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_em_dev_init, + .eth_dev_uninit = eth_em_dev_uninit, .dev_private_size = sizeof(struct e1000_adapter), }; @@ -565,6 +600,8 @@ eth_em_start(struct rte_eth_dev *dev) } } + hw->adapter_stopped = FALSE; + PMD_INIT_LOG(DEBUG, "<<"); return (0); @@ -610,6 +647,7 @@ eth_em_close(struct rte_eth_dev *dev) struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); eth_em_stop(dev); + hw->adapter_stopped = TRUE; e1000_phy_hw_reset(hw); em_release_manageability(hw); em_hw_control_release(hw); diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c index 4415155..05a5500 100644 --- a/lib/librte_pmd_e1000/igb_ethdev.c +++ b/lib/librte_pmd_e1000/igb_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -564,6 +564,7 @@ eth_igb_dev_init(struct rte_eth_dev *eth_dev) goto err_late; } hw->mac.get_link_status = 1; + hw->adapter_stopped = FALSE; /* Indicate SOL/IDER usage */ if (e1000_check_reset_block(hw) < 0) { @@ -608,6 +609,45 @@ err_late: return (error); } +static int +eth_igb_dev_uninit(struct rte_eth_dev *eth_dev) +{ + struct rte_pci_device *pci_dev; + struct e1000_hw *hw; + + PMD_INIT_FUNC_TRACE(); + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return -EPERM; + + hw = E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + pci_dev = eth_dev->pci_dev; + + if (hw->adapter_stopped == FALSE) + eth_igb_close(eth_dev); + + eth_dev->dev_ops = NULL; + eth_dev->rx_pkt_burst = NULL; + eth_dev->tx_pkt_burst = NULL; + + /* Reset any pending lock */ + igb_reset_swfw_lock(hw); + + rte_free(eth_dev->data->mac_addrs); + eth_dev->data->mac_addrs = NULL; + + /* uninitialize PF if max_vfs not zero */ + igb_pf_host_uninit(eth_dev); + + /* disable uio intr before callback unregister */ + rte_intr_disable(&(pci_dev->intr_handle)); + rte_intr_callback_unregister(&(pci_dev->intr_handle), + eth_igb_interrupt_handler, (void *)eth_dev); + + return 0; +} + + /* * Virtual Function device init */ @@ -639,6 +679,7 @@ eth_igbvf_dev_init(struct rte_eth_dev *eth_dev) hw->device_id = pci_dev->id.device_id; hw->vendor_id = pci_dev->id.vendor_id; hw->hw_addr = (void *)pci_dev->mem_resource[0].addr; + hw->adapter_stopped = FALSE; /* Initialize the shared code (base driver) */ diag = e1000_setup_init_funcs(hw, TRUE); @@ -679,13 +720,39 @@ eth_igbvf_dev_init(struct rte_eth_dev *eth_dev) return 0; } +static int +eth_igbvf_dev_uninit(struct rte_eth_dev *eth_dev) +{ + struct e1000_hw *hw; + + PMD_INIT_FUNC_TRACE(); + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return -EPERM; + + hw = E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + if (hw->adapter_stopped == FALSE) + igbvf_dev_close(eth_dev); + + eth_dev->dev_ops = NULL; + eth_dev->rx_pkt_burst = NULL; + eth_dev->tx_pkt_burst = NULL; + + rte_free(eth_dev->data->mac_addrs); + eth_dev->data->mac_addrs = NULL; + + return 0; +} + static struct eth_driver rte_igb_pmd = { { .name = "rte_igb_pmd", .id_table = pci_id_igb_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_igb_dev_init, + .eth_dev_uninit = eth_igb_dev_uninit, .dev_private_size = sizeof(struct e1000_adapter), }; @@ -696,9 +763,10 @@ static struct eth_driver rte_igbvf_pmd = { { .name = "rte_igbvf_pmd", .id_table = pci_id_igbvf_map, - .drv_flags = RTE_PCI_DRV_NEED_MAPPING, + .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE, }, .eth_dev_init = eth_igbvf_dev_init, + .eth_dev_uninit = eth_igbvf_dev_uninit, .dev_private_size = sizeof(struct e1000_adapter), }; @@ -780,6 +848,7 @@ eth_igb_start(struct rte_eth_dev *dev) PMD_INIT_LOG(ERR, "Unable to initialize the hardware"); return (-EIO); } + hw->adapter_stopped = FALSE; E1000_WRITE_REG(hw, E1000_VET, ETHER_TYPE_VLAN << 16 | ETHER_TYPE_VLAN); @@ -989,6 +1058,8 @@ eth_igb_close(struct rte_eth_dev *dev) struct rte_eth_link link; eth_igb_stop(dev); + hw->adapter_stopped = TRUE; + e1000_phy_hw_reset(hw); igb_release_manageability(hw); igb_hw_control_release(hw); @@ -2227,6 +2298,7 @@ igbvf_dev_start(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); hw->mac.ops.reset_hw(hw); + hw->adapter_stopped = FALSE; /* Set all vfta */ igbvf_set_vfta_all(dev,1); @@ -2270,6 +2342,7 @@ igbvf_dev_close(struct rte_eth_dev *dev) e1000_reset_hw(hw); igbvf_dev_stop(dev); + hw->adapter_stopped = TRUE; } static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on) diff --git a/lib/librte_pmd_e1000/igb_pf.c b/lib/librte_pmd_e1000/igb_pf.c index 2d49379..87fd812 100644 --- a/lib/librte_pmd_e1000/igb_pf.c +++ b/lib/librte_pmd_e1000/igb_pf.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -127,6 +127,28 @@ void igb_pf_host_init(struct rte_eth_dev *eth_dev) return; } +void igb_pf_host_uninit(struct rte_eth_dev *eth_dev) +{ + struct e1000_vf_info **vfinfo; + uint16_t vf_num; + + PMD_INIT_FUNC_TRACE(); + + vfinfo = E1000_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; +} + #define E1000_RAH_POOLSEL_SHIFT (18) int igb_pf_host_configure(struct rte_eth_dev *eth_dev) {