From patchwork Thu Feb 26 02:31:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 3736 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 B27DF5936; Thu, 26 Feb 2015 03:32:05 +0100 (CET) Received: from mail-ie0-f176.google.com (mail-ie0-f176.google.com [209.85.223.176]) by dpdk.org (Postfix) with ESMTP id B10D8591C for ; Thu, 26 Feb 2015 03:32:04 +0100 (CET) Received: by ierx19 with SMTP id x19so10513223ier.3 for ; Wed, 25 Feb 2015 18:32:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=SFjPXxzayDTXmTQJaOUwj+xXVYP9FpXhBbk/tMoBtwY=; b=R8/wD0mHVAd6f1steMUxVf28R9MjBvd0l1cZokSRGqisVzc1sq/pIXCRfWztNnLSy/ GF0iTVcGw+6lylilTNMC0cGRxX1lWQwgE51ec2kHv6EwomAxQrSFexVHdgHdGV5CLBFT Hulvfw87bk3yZmUz51MzppdujcxqcBWx2Ic4tVv3B7T4QRXXutP5/v3dzvCQs2UFoYZN AsA6JBFyMHDyHMC0HedX7kbD9poZ1bDIX8tBtl5kEyXkZb3XTxkMdyN+ldQnEOVsAmJc sVpkTYawNHz8vgODc89U1IfCqHEBkp7L7Z1zHSml0EQxwnBV00DnG0oX5uXcHyhV2aAB hqCA== X-Gm-Message-State: ALoCoQkGiJDOdPWPZXmPYDDcLV+uGPZUKlAGl2f9CjgxWt4PfAWpZFxweWkZr5UoCVAPFux2TKPB X-Received: by 10.107.129.85 with SMTP id c82mr8672903iod.81.1424917924178; Wed, 25 Feb 2015 18:32:04 -0800 (PST) Received: from urahara.brocade.com (static-50-53-82-155.bvtn.or.frontiernet.net. [50.53.82.155]) by mx.google.com with ESMTPSA id y5sm336741ign.7.2015.02.25.18.32.03 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 25 Feb 2015 18:32:03 -0800 (PST) From: Stephen Hemminger To: Yong Wang Date: Wed, 25 Feb 2015 18:31:56 -0800 Message-Id: <1424917922-1979-1-git-send-email-stephen@networkplumber.org> X-Mailer: git-send-email 2.1.4 Cc: dev@dpdk.org Subject: [dpdk-dev] [PATCH 1/7] vmxnet3: enable VLAN filtering 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" Support the VLAN filter functionality of the VMXNET3 interface. Signed-off-by: Stephen Hemminger --- v2 -- incorporate comments from Yong Wang lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 105 +++++++++++++++++++++++++++++--- lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 3 +- lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 31 +--------- 3 files changed, 101 insertions(+), 38 deletions(-) diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c index 6068c60..23b4558 100644 --- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c +++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c @@ -87,6 +87,12 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats); static void vmxnet3_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info); +static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev, + uint16_t vid, int on); +static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask); +static void vmxnet3_dev_vlan_offload_set_clear(struct rte_eth_dev *dev, + int mask, int clear); + #if PROCESS_SYS_EVENTS == 1 static void vmxnet3_process_events(struct vmxnet3_hw *); #endif @@ -113,6 +119,8 @@ static struct eth_dev_ops vmxnet3_eth_dev_ops = { .link_update = vmxnet3_dev_link_update, .stats_get = vmxnet3_dev_stats_get, .dev_infos_get = vmxnet3_dev_info_get, + .vlan_filter_set = vmxnet3_dev_vlan_filter_set, + .vlan_offload_set = vmxnet3_dev_vlan_offload_set, .rx_queue_setup = vmxnet3_dev_rx_queue_setup, .rx_queue_release = vmxnet3_dev_rx_queue_release, .tx_queue_setup = vmxnet3_dev_tx_queue_setup, @@ -371,7 +379,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev) Vmxnet3_DSDevRead *devRead = &shared->devRead; uint32_t *mac_ptr; uint32_t val, i; - int ret; + int ret, mask; shared->magic = VMXNET3_REV1_MAGIC; devRead->misc.driverInfo.version = VMXNET3_DRIVER_VERSION_NUM; @@ -442,9 +450,6 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev) if (dev->data->dev_conf.rxmode.hw_ip_checksum) devRead->misc.uptFeatures |= VMXNET3_F_RXCSUM; - if (dev->data->dev_conf.rxmode.hw_vlan_strip) - devRead->misc.uptFeatures |= VMXNET3_F_RXVLAN; - if (port_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) { ret = vmxnet3_rss_configure(dev); if (ret != VMXNET3_SUCCESS) @@ -456,11 +461,14 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev) devRead->rssConfDesc.confPA = hw->rss_confPA; } - if (dev->data->dev_conf.rxmode.hw_vlan_filter) { - ret = vmxnet3_vlan_configure(dev); - if (ret != VMXNET3_SUCCESS) - return ret; - } + mask = 0; + if (dev->data->dev_conf.rxmode.hw_vlan_strip) + mask |= ETH_VLAN_STRIP_MASK; + + if (dev->data->dev_conf.rxmode.hw_vlan_filter) + mask |= ETH_VLAN_FILTER_MASK; + + vmxnet3_dev_vlan_offload_set_clear(dev, mask, 1); PMD_INIT_LOG(DEBUG, "Writing MAC Address : %02x:%02x:%02x:%02x:%02x:%02x", @@ -696,8 +704,13 @@ static void vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev) { struct vmxnet3_hw *hw = dev->data->dev_private; + uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable; + memset(vf_table, 0, VMXNET3_VFT_TABLE_SIZE); vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 1); + + VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, + VMXNET3_CMD_UPDATE_VLAN_FILTERS); } /* Promiscuous supported only if Vmxnet3_DriverShared is initialized in adapter */ @@ -705,8 +718,12 @@ static void vmxnet3_dev_promiscuous_disable(struct rte_eth_dev *dev) { struct vmxnet3_hw *hw = dev->data->dev_private; + uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable; + memcpy(vf_table, hw->shadow_vfta, VMXNET3_VFT_TABLE_SIZE); vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 0); + VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, + VMXNET3_CMD_UPDATE_VLAN_FILTERS); } /* Allmulticast supported only if Vmxnet3_DriverShared is initialized in adapter */ @@ -727,6 +744,76 @@ vmxnet3_dev_allmulticast_disable(struct rte_eth_dev *dev) vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_ALL_MULTI, 0); } +/* Enable/disable filter on vlan */ +static int +vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vid, int on) +{ + struct vmxnet3_hw *hw = dev->data->dev_private; + struct Vmxnet3_RxFilterConf *rxConf = &hw->shared->devRead.rxFilterConf; + uint32_t *vf_table = rxConf->vfTable; + + /* save state for restore */ + if (on) + VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, vid); + else + VMXNET3_CLEAR_VFTABLE_ENTRY(hw->shadow_vfta, vid); + + /* don't change active filter if in promiscious mode */ + if (rxConf->rxMode & VMXNET3_RXM_PROMISC) + return 0; + + /* set in hardware */ + if (on) + VMXNET3_SET_VFTABLE_ENTRY(vf_table, vid); + else + VMXNET3_CLEAR_VFTABLE_ENTRY(vf_table, vid); + + VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, + VMXNET3_CMD_UPDATE_VLAN_FILTERS); + return 0; +} + +static void +vmxnet3_dev_vlan_offload_set_clear(struct rte_eth_dev *dev, + int mask, int clear) +{ + struct vmxnet3_hw *hw = dev->data->dev_private; + Vmxnet3_DSDevRead *devRead = &hw->shared->devRead; + uint32_t *vf_table = devRead->rxFilterConf.vfTable; + + if (mask & ETH_VLAN_STRIP_MASK) + devRead->misc.uptFeatures |= UPT1_F_RXVLAN; + else + devRead->misc.uptFeatures &= ~UPT1_F_RXVLAN; + + VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, + VMXNET3_CMD_UPDATE_FEATURE); + + if (mask & ETH_VLAN_FILTER_MASK) { + if (clear) { + memset(hw->shadow_vfta, 0, + VMXNET3_VFT_TABLE_SIZE); + /* allow untagged pkts */ + VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, 0); + } + memcpy(vf_table, hw->shadow_vfta, VMXNET3_VFT_TABLE_SIZE); + } else { + /* allow any pkts -- no filtering */ + if (clear) + memset(hw->shadow_vfta, 0xff, VMXNET3_VFT_TABLE_SIZE); + memset(vf_table, 0xff, VMXNET3_VFT_TABLE_SIZE); + } + + VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, + VMXNET3_CMD_UPDATE_VLAN_FILTERS); +} + +static void +vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask) +{ + vmxnet3_dev_vlan_offload_set_clear(dev, mask, 0); +} + #if PROCESS_SYS_EVENTS == 1 static void vmxnet3_process_events(struct vmxnet3_hw *hw) diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h index 09993cf..e97e3ca 100644 --- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h +++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h @@ -121,6 +121,8 @@ struct vmxnet3_hw { VMXNET3_RSSConf *rss_conf; uint64_t rss_confPA; vmxnet3_mf_table_t *mf_table; + uint32_t shadow_vfta[VMXNET3_VFT_SIZE]; +#define VMXNET3_VFT_TABLE_SIZE (VMXNET3_VFT_SIZE * sizeof(uint32_t)) }; #define VMXNET3_GET_ADDR_LO(reg) ((uint32_t)(reg)) @@ -173,7 +175,6 @@ int vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, int vmxnet3_dev_rxtx_init(struct rte_eth_dev *dev); int vmxnet3_rss_configure(struct rte_eth_dev *dev); -int vmxnet3_vlan_configure(struct rte_eth_dev *dev); uint16_t vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c index 4d8a010..5fe3de5 100644 --- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c +++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c @@ -738,9 +738,9 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev, return -EINVAL; } - if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOOFFLOADS) != - ETH_TXQ_FLAGS_NOOFFLOADS) { - PMD_INIT_LOG(ERR, "TX not support offload function yet"); + if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMS) != + ETH_TXQ_FLAGS_NOXSUMS) { + PMD_INIT_LOG(ERR, "TX no support for checksum offload yet"); return -EINVAL; } @@ -1045,28 +1045,3 @@ vmxnet3_rss_configure(struct rte_eth_dev *dev) return VMXNET3_SUCCESS; } - -/* - * Configure VLAN Filter feature - */ -int -vmxnet3_vlan_configure(struct rte_eth_dev *dev) -{ - uint8_t i; - struct vmxnet3_hw *hw = dev->data->dev_private; - uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable; - - PMD_INIT_FUNC_TRACE(); - - /* Verify if this tag is already set */ - for (i = 0; i < VMXNET3_VFT_SIZE; i++) { - /* Filter all vlan tags out by default */ - vf_table[i] = 0; - /* To-Do: Provide another routine in dev_ops for user config */ - - PMD_INIT_LOG(DEBUG, "Registering VLAN portid: %"PRIu8" tag %u", - dev->data->port_id, vf_table[i]); - } - - return VMXNET3_SUCCESS; -}