From patchwork Fri Mar 6 00:10:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 3887 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 E34305A8A; Fri, 6 Mar 2015 01:10:45 +0100 (CET) Received: from mail-pa0-f42.google.com (mail-pa0-f42.google.com [209.85.220.42]) by dpdk.org (Postfix) with ESMTP id 089045A73 for ; Fri, 6 Mar 2015 01:10:43 +0100 (CET) Received: by paceu11 with SMTP id eu11so32794581pac.1 for ; Thu, 05 Mar 2015 16:10:43 -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:in-reply-to :references; bh=c5XulzRYInbDuE8ghYK2eg0BJ29KTml1G5ZPn762COw=; b=QMakSzjTpvxpaQ1MSzWbnywwLa7LL/Cvgs/STrLXNWaRGdWG6Z2hL06ECMCT04fVe5 cbqQ20cYwZ7XaAZAYaydPpoPaRziiFWWm0mqx+ecZaD692b8k7S2ayHtyxCNLPqyhhZ2 sa0qLOL/KcomqPKjO8nm7EsaPHz3Lh4+gekQeBD0QgNwJ3JHrHcm6n8LgNtiTIjc02Hc HPlFX/L2zqTRrlUtlHD7M4E0fMXtsImBOeKaWYEQkHGiapLm0TzI/0Z+TLGv3l1dTEvk i4/9iyJvcYc+700liyCjHBlzI1njRBxVh5yjoe7XfEjyL9iE97sqIpcvLx6gqRITejC/ 2bKg== X-Gm-Message-State: ALoCoQn4lR3rgtVVuwr+mOoopvq7S+W+GB4Gj0ATvfrvf0BnZETQyd5+kKMesj5rKsXbJdKaVwxr X-Received: by 10.70.44.78 with SMTP id c14mr19968925pdm.113.1425600643230; Thu, 05 Mar 2015 16:10:43 -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 ms5sm7940550pbb.59.2015.03.05.16.10.42 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 05 Mar 2015 16:10:42 -0800 (PST) From: Stephen Hemminger To: Yong Wang Date: Thu, 5 Mar 2015 16:10:27 -0800 Message-Id: <1425600635-20628-3-git-send-email-stephen@networkplumber.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1425600635-20628-1-git-send-email-stephen@networkplumber.org> References: <1425600635-20628-1-git-send-email-stephen@networkplumber.org> Cc: dev@dpdk.org, Stephen Hemminger Subject: [dpdk-dev] [PATCH v3 02/10] 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" From: Stephen Hemminger Support the VLAN filter functionality of the VMXNET3 interface. Signed-off-by: Stephen Hemminger Acked-by: Yong Wang --- lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 105 +++++++++++++++++++++++++++++--- lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 4 +- lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 31 +--------- 3 files changed, 102 insertions(+), 38 deletions(-) diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c index 4c882ee..f4c2f12 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, @@ -398,7 +406,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; @@ -470,9 +478,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) @@ -484,11 +489,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", @@ -720,8 +728,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 */ @@ -729,8 +742,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 */ @@ -751,6 +768,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..e9d67a7 100644 --- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h +++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h @@ -121,8 +121,11 @@ 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)) #define VMXNET3_GET_ADDR_HI(reg) ((uint32_t)(((uint64_t)(reg)) >> 32)) @@ -173,7 +176,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; -}