From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 7EEBEB3AD for ; Tue, 23 Sep 2014 05:24:06 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP; 22 Sep 2014 20:21:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,577,1406617200"; d="scan'208";a="595345776" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga001.fm.intel.com with ESMTP; 22 Sep 2014 20:30:06 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id s8N3U4k8010976; Tue, 23 Sep 2014 11:30:04 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id s8N3U2Xq015483; Tue, 23 Sep 2014 11:30:04 +0800 Received: (from jijiangl@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id s8N3U1Nm015479; Tue, 23 Sep 2014 11:30:01 +0800 From: Jijiang Liu To: dev@dpdk.org Date: Tue, 23 Sep 2014 11:29:50 +0800 Message-Id: <1411442991-15386-5-git-send-email-jijiang.liu@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1411442991-15386-1-git-send-email-jijiang.liu@intel.com> References: <1411442991-15386-1-git-send-email-jijiang.liu@intel.com> Subject: [dpdk-dev] [PATCH 4/5]i40e:add VF MACVLAN filter implementation in librte_pmd_i40e 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: , X-List-Received-Date: Tue, 23 Sep 2014 03:24:07 -0000 Add i40e_vf_mac_filter_set() function to support perfect match and hash match filter of MAC address and VLAN ID for a VF. Signed-off-by: Jijiang Liu Acked-by: Helin Zhang Acked-by: Jingjing Wu Acked-by: Changchun Ouyang --- lib/librte_pmd_i40e/i40e_ethdev.c | 117 ++++++++++++++++++++++++++++++++++++- 1 files changed, 114 insertions(+), 3 deletions(-) diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c index bdab17c..66ad3bb 100644 --- a/lib/librte_pmd_i40e/i40e_ethdev.c +++ b/lib/librte_pmd_i40e/i40e_ethdev.c @@ -1591,6 +1591,118 @@ i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index) memset(&pf->dev_addr, 0, sizeof(struct ether_addr)); } +/* Set perfect match or hash match of MAC and VLAN for a VF */ +static int +i40e_vf_mac_filter_set(struct i40e_pf *pf, + struct rte_eth_mac_filter *filter, + bool add) +{ + struct i40e_hw *hw; + struct i40e_mac_filter_info mac_filter; + struct ether_addr old_mac; + struct ether_addr *new_mac; + struct i40e_pf_vf *vf = NULL; + uint16_t vf_id; + int ret; + + if (pf == NULL) { + PMD_DRV_LOG(ERR, "Invalid PF argument\n"); + return -EINVAL; + } + hw = I40E_PF_TO_HW(pf); + + if (filter == NULL) { + PMD_DRV_LOG(ERR, "Invalid mac filter argument\n"); + return -EINVAL; + } + + new_mac = &filter->mac_addr; + + if (is_zero_ether_addr(new_mac)) { + PMD_DRV_LOG(ERR, "Invalid ethernet address\n"); + return -EINVAL; + } + + vf_id = filter->id; + + if (vf_id > pf->vf_num - 1 || !pf->vfs) { + PMD_DRV_LOG(ERR, "Invalid argument\n"); + return -EINVAL; + } + vf = &pf->vfs[vf_id]; + + if (add && is_same_ether_addr(new_mac, &(pf->dev_addr))) { + PMD_DRV_LOG(INFO, "Ignore adding permanent MAC address\n"); + return -EINVAL; + } + + if (add) { + (void)rte_memcpy(&old_mac, hw->mac.addr, ETHER_ADDR_LEN); + (void)rte_memcpy(hw->mac.addr, new_mac->addr_bytes, + ETHER_ADDR_LEN); + (void)rte_memcpy(&mac_filter.mac_addr, &filter->mac_addr, + ETHER_ADDR_LEN); + + mac_filter.filter_type = filter->filter_type; + mac_filter.queue_id = filter->queue_id; + ret = i40e_vsi_add_mac(vf->vsi, &mac_filter); + if (ret != I40E_SUCCESS) { + PMD_DRV_LOG(ERR, "Failed to add MAC filter\n"); + return -1; + } + ether_addr_copy(new_mac, &pf->dev_addr); + } else { + (void)rte_memcpy(hw->mac.addr, hw->mac.perm_addr, + ETHER_ADDR_LEN); + ret = i40e_vsi_delete_mac(vf->vsi, &filter->mac_addr); + if (ret != I40E_SUCCESS) { + PMD_DRV_LOG(ERR, "Failed to delete MAC filter\n"); + return -1; + } + + /* Clear device address as it has been removed */ + if (is_same_ether_addr(&(pf->dev_addr), new_mac)) + memset(&pf->dev_addr, 0, sizeof(struct ether_addr)); + } + + return 0; +} + +static int +i40e_mac_filter_handle(struct i40e_pf *pf, enum rte_filter_op filter_op, + void *arg) +{ + struct rte_eth_mac_filter *filter; + struct i40e_hw *hw = I40E_PF_TO_HW(pf); + int ret = I40E_NOT_SUPPORTED; + + filter = (struct rte_eth_mac_filter *)(arg); + + switch (filter_op) { + case RTE_ETH_FILTER_OP_NONE: + ret = I40E_SUCCESS; + break; + case RTE_ETH_FILTER_OP_ADD: + i40e_pf_disable_irq0(hw); + if (!filter->pf_vf_flag) + ret = i40e_vf_mac_filter_set(pf, filter, 1); + i40e_pf_enable_irq0(hw); + break; + case RTE_ETH_FILTER_OP_DELETE: + i40e_pf_disable_irq0(hw); + if (!filter->pf_vf_flag) + ret = i40e_vf_mac_filter_set(pf, filter, 0); + i40e_pf_enable_irq0(hw); + break; + default: + PMD_DRV_LOG(ERR, "unknown operation %u\n", filter_op); + ret = I40E_ERR_PARAM; + break; + } + + return ret; +} + static int i40e_dev_rss_reta_update(struct rte_eth_dev *dev, struct rte_eth_rss_reta *reta_conf) @@ -4224,16 +4336,15 @@ static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type, enum rte_filter_op filter_op, void *arg) { + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); int ret = 0; - if (dev == NULL) - return -EINVAL; - if (arg == NULL && filter_op != RTE_ETH_FILTER_OP_NONE) return -EINVAL; switch (filter_type) { case RTE_ETH_FILTER_MACVLAN: + ret = i40e_mac_filter_handle(pf, filter_op, arg); break; default: PMD_DRV_LOG(ERR, "unsupported filter type %u\n", filter_type); -- 1.7.7.6