From patchwork Sat Feb 25 01:23:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allain Legacy X-Patchwork-Id: 20749 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 EAB54F966; Sat, 25 Feb 2017 02:25:05 +0100 (CET) Received: from mail5.wrs.com (mail5.windriver.com [192.103.53.11]) by dpdk.org (Postfix) with ESMTP id B205A2BB4 for ; Sat, 25 Feb 2017 02:24:04 +0100 (CET) Received: from ALA-HCA.corp.ad.wrs.com (ala-hca.corp.ad.wrs.com [147.11.189.40]) by mail5.wrs.com (8.15.2/8.15.2) with ESMTPS id v1P1O3C2007042 (version=TLSv1 cipher=AES128-SHA bits=128 verify=OK); Fri, 24 Feb 2017 17:24:03 -0800 Received: from yow-cgts4-lx.wrs.com (128.224.145.137) by ALA-HCA.corp.ad.wrs.com (147.11.189.50) with Microsoft SMTP Server (TLS) id 14.3.294.0; Fri, 24 Feb 2017 17:24:02 -0800 From: Allain Legacy To: CC: Date: Fri, 24 Feb 2017 20:23:14 -0500 Message-ID: <1487985795-136044-16-git-send-email-allain.legacy@windriver.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1487985795-136044-1-git-send-email-allain.legacy@windriver.com> References: <1487985795-136044-1-git-send-email-allain.legacy@windriver.com> MIME-Version: 1.0 X-Originating-IP: [128.224.145.137] Subject: [dpdk-dev] [PATCH 15/16] net/avp: device start and stop operations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Adds support for device start and stop functions. This allows an application to control the administrative state of an AVP device. Stopping the device will notify the host application to stop sending packets on that device's receive queues. Signed-off-by: Allain Legacy Signed-off-by: Matt Peters --- drivers/net/avp/avp_ethdev.c | 157 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c index 618deaf..8006ed9 100644 --- a/drivers/net/avp/avp_ethdev.c +++ b/drivers/net/avp/avp_ethdev.c @@ -67,6 +67,9 @@ static int avp_dev_create(struct rte_pci_device *pci_dev, static int eth_avp_dev_uninit(struct rte_eth_dev *eth_dev); static int avp_dev_configure(struct rte_eth_dev *dev); +static int avp_dev_start(struct rte_eth_dev *dev); +static void avp_dev_stop(struct rte_eth_dev *dev); +static void avp_dev_close(struct rte_eth_dev *dev); static void avp_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info); static void avp_vlan_offload_set(struct rte_eth_dev *dev, int mask); @@ -156,6 +159,9 @@ static void avp_dev_stats_get(struct rte_eth_dev *dev, */ static const struct eth_dev_ops avp_eth_dev_ops = { .dev_configure = avp_dev_configure, + .dev_start = avp_dev_start, + .dev_stop = avp_dev_stop, + .dev_close = avp_dev_close, .dev_infos_get = avp_dev_info_get, .vlan_offload_set = avp_vlan_offload_set, .stats_get = avp_dev_stats_get, @@ -343,6 +349,24 @@ struct avp_queue { } static int +avp_dev_ctrl_set_link_state(struct rte_eth_dev *eth_dev, unsigned state) +{ + struct avp_dev *avp = + RTE_AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + struct rte_avp_request request; + int ret; + + /* setup a link state change request */ + memset(&request, 0, sizeof(request)); + request.req_id = RTE_AVP_REQ_CFG_NETWORK_IF; + request.if_up = state; + + ret = avp_dev_process_request(avp, &request); + + return ret == 0 ? request.result : ret; +} + +static int avp_dev_ctrl_set_config(struct rte_eth_dev *eth_dev, struct rte_avp_device_config *config) { @@ -795,6 +819,31 @@ struct avp_queue { } static int +avp_dev_disable_interrupts(struct rte_eth_dev *eth_dev) +{ + struct rte_pci_device *pci_dev = AVP_DEV_TO_PCI(eth_dev); + void *registers = pci_dev->mem_resource[RTE_AVP_PCI_MMIO_BAR].addr; + int ret; + + if (registers == NULL) + return 0; + + /* inform the device that all interrupts are disabled */ + RTE_AVP_WRITE32(RTE_AVP_NO_INTERRUPTS_MASK, + RTE_PTR_ADD(registers, RTE_AVP_INTERRUPT_MASK_OFFSET)); + + /* enable UIO interrupt handling */ + ret = rte_intr_disable(&(pci_dev->intr_handle)); + if (ret < 0) { + PMD_DRV_LOG(ERR, + "Failed to enable UIO interrupts, ret=%d\n", ret); + return ret; + } + + return 0; +} + +static int avp_dev_setup_interrupts(struct rte_eth_dev *eth_dev) { struct rte_pci_device *pci_dev = AVP_DEV_TO_PCI(eth_dev); @@ -2044,6 +2093,114 @@ struct avp_queue { return ret; } +static int +avp_dev_start(struct rte_eth_dev *eth_dev) +{ + struct avp_dev *avp = + RTE_AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + int ret; + + rte_spinlock_lock(&avp->lock); + if (avp->flags & RTE_AVP_F_DETACHED) { + PMD_DRV_LOG(ERR, + "Operation not supported during " + "VM live migration\n"); + ret = -ENOTSUP; + goto unlock; + } + + /* disable features that we do not support */ + eth_dev->data->dev_conf.rxmode.hw_ip_checksum = 0; + eth_dev->data->dev_conf.rxmode.hw_vlan_filter = 0; + eth_dev->data->dev_conf.rxmode.hw_vlan_extend = 0; + eth_dev->data->dev_conf.rxmode.hw_strip_crc = 0; + + /* update link state */ + ret = avp_dev_ctrl_set_link_state(eth_dev, 1); + if (ret < 0) { + PMD_DRV_LOG(ERR, + "Link state change failed by host, ret=%d\n", ret); + goto unlock; + } + + /* remember current link state */ + avp->flags |= RTE_AVP_F_LINKUP; + + ret = 0; + +unlock: + rte_spinlock_unlock(&avp->lock); + return ret; +} + +static void +avp_dev_stop(struct rte_eth_dev *eth_dev) +{ + struct avp_dev *avp = + RTE_AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + int ret; + + rte_spinlock_lock(&avp->lock); + if (avp->flags & RTE_AVP_F_DETACHED) { + PMD_DRV_LOG(ERR, + "Operation not supported during " + "VM live migration\n"); + goto unlock; + } + + /* remember current link state */ + avp->flags &= ~RTE_AVP_F_LINKUP; + + /* update link state */ + ret = avp_dev_ctrl_set_link_state(eth_dev, 0); + if (ret < 0) { + PMD_DRV_LOG(ERR, + "Link state change failed by host, ret=%d\n", ret); + goto unlock; + } + +unlock: + rte_spinlock_unlock(&avp->lock); + return; +} + +static void +avp_dev_close(struct rte_eth_dev *eth_dev) +{ + struct avp_dev *avp = + RTE_AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + int ret; + + rte_spinlock_lock(&avp->lock); + if (avp->flags & RTE_AVP_F_DETACHED) { + PMD_DRV_LOG(ERR, + "Operation not supported during " + "VM live migration\n"); + goto unlock; + } + + /* remember current link state */ + avp->flags &= ~RTE_AVP_F_LINKUP; + avp->flags &= ~RTE_AVP_F_CONFIGURED; + + ret = avp_dev_disable_interrupts(eth_dev); + if (ret < 0) { + PMD_DRV_LOG(ERR, "Failed to disable interrupts\n"); + /* continue */ + } + + /* update device state */ + ret = avp_dev_ctrl_shutdown(eth_dev); + if (ret < 0) { + PMD_DRV_LOG(ERR, "Device shutdown failed by host, ret=%d\n", + ret); + goto unlock; + } + +unlock: + rte_spinlock_unlock(&avp->lock); + return; +} static int avp_dev_link_update(struct rte_eth_dev *eth_dev,