From patchwork Tue Jun 2 02:58:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "He, Shaopeng" X-Patchwork-Id: 5053 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 254C6C316; Tue, 2 Jun 2015 04:59:19 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id E9853C312 for ; Tue, 2 Jun 2015 04:59:16 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP; 01 Jun 2015 19:59:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,536,1427785200"; d="scan'208";a="703688673" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga001.jf.intel.com with ESMTP; 01 Jun 2015 19:59:15 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id t522xCJG021859; Tue, 2 Jun 2015 10:59:12 +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 t522x9lu021740; Tue, 2 Jun 2015 10:59:11 +0800 Received: (from heshaope@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t522x9sX021736; Tue, 2 Jun 2015 10:59:09 +0800 From: Shaopeng He To: dev@dpdk.org Date: Tue, 2 Jun 2015 10:58:56 +0800 Message-Id: <1433213937-21690-3-git-send-email-shaopeng.he@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1433213937-21690-1-git-send-email-shaopeng.he@intel.com> References: <1433213937-21690-1-git-send-email-shaopeng.he@intel.com> Cc: Shaopeng He Subject: [dpdk-dev] [PATCH 2/3] fm10k: add MAC filter 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" MAC filter function was newly added, each PF and VF can have up to 64 MAC addresses. VF filter needs support from PF host, which is not available now. Signed-off-by: Shaopeng He --- drivers/net/fm10k/fm10k.h | 3 +- drivers/net/fm10k/fm10k_ethdev.c | 90 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/drivers/net/fm10k/fm10k.h b/drivers/net/fm10k/fm10k.h index 3b95b72..f5be5f8 100644 --- a/drivers/net/fm10k/fm10k.h +++ b/drivers/net/fm10k/fm10k.h @@ -110,7 +110,7 @@ #define FM10K_VLAN_TAG_SIZE 4 /* Maximum number of MAC addresses per PF/VF */ -#define FM10K_MAX_MACADDR_NUM 1 +#define FM10K_MAX_MACADDR_NUM 64 #define FM10K_UINT32_BIT_SIZE (CHAR_BIT * sizeof(uint32_t)) #define FM10K_VFTA_SIZE (4096 / FM10K_UINT32_BIT_SIZE) @@ -125,6 +125,7 @@ struct fm10k_macvlan_filter_info { uint16_t vlan_num; /* Total VLAN number */ + uint16_t mac_num; /* Total mac number */ uint32_t vfta[FM10K_VFTA_SIZE]; /* VLAN bitmap */ }; diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c index d2f3e44..4f23bf1 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -54,6 +54,10 @@ #define BIT_MASK_PER_UINT32 ((1 << CHARS_PER_UINT32) - 1) static void fm10k_close_mbx_service(struct fm10k_hw *hw); +static int +fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on); +static void +fm10k_MAC_filter_set(struct rte_eth_dev *dev, const u8 *mac, bool add); static void fm10k_mbx_initlock(struct fm10k_hw *hw) @@ -668,14 +672,11 @@ fm10k_dev_start(struct rte_eth_dev *dev) } if (hw->mac.default_vid && hw->mac.default_vid <= ETHER_MAX_VLAN_ID) { - fm10k_mbx_lock(hw); /* Update default vlan */ - hw->mac.ops.update_vlan(hw, hw->mac.default_vid, 0, true); + fm10k_vlan_filter_set(dev, hw->mac.default_vid, true); /* Add default mac/vlan filter to PF/Switch manger */ - hw->mac.ops.update_uc_addr(hw, hw->mac.dglort_map, hw->mac.addr, - hw->mac.default_vid, true, 0); - fm10k_mbx_unlock(hw); + fm10k_MAC_filter_set(dev, hw->mac.addr, true); } return 0; @@ -781,7 +782,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev, dev_info->max_rx_pktlen = FM10K_MAX_PKT_SIZE; dev_info->max_rx_queues = hw->mac.max_queues; dev_info->max_tx_queues = hw->mac.max_queues; - dev_info->max_mac_addrs = 1; + dev_info->max_mac_addrs = FM10K_MAX_MACADDR_NUM; dev_info->max_hash_mac_addrs = 0; dev_info->max_vfs = FM10K_MAX_VF_NUM; dev_info->max_vmdq_pools = ETH_64_POOLS; @@ -820,6 +821,7 @@ static int fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) { s32 result; + uint16_t mac_num = 0; uint32_t vid_idx, vid_bit, mac_index; struct fm10k_hw *hw; struct fm10k_macvlan_filter_info *macvlan; @@ -864,9 +866,15 @@ fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) mac_index++) { if (is_zero_ether_addr(&data->mac_addrs[mac_index])) continue; + if (mac_num > macvlan->mac_num - 1) { + PMD_INIT_LOG(ERR, "MAC address number " + "not match"); + break; + } fm10k_update_uc_addr(hw, hw->mac.dglort_map, data->mac_addrs[mac_index].addr_bytes, vlan_id, on, 0); + mac_num++; } } fm10k_mbx_unlock(hw); @@ -876,6 +884,71 @@ fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) return (-EIO); } +/* Add/Remove a MAC address, and update filters */ +static void +fm10k_MAC_filter_set(struct rte_eth_dev *dev, const u8 *mac, bool add) +{ + uint32_t i, j, k; + struct fm10k_hw *hw; + struct fm10k_macvlan_filter_info *macvlan; + + hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private); + macvlan = FM10K_DEV_PRIVATE_TO_MACVLAN(dev->data->dev_private); + + /* @todo - add support for the VF */ + if (hw->mac.type != fm10k_mac_pf) + return; + + fm10k_mbx_lock(hw); + i = 0; + for (j = 0; j < FM10K_VFTA_SIZE; j++) { + if (macvlan->vfta[j]) { + for (k = 0; k < FM10K_UINT32_BIT_SIZE; k++) { + if (macvlan->vfta[j] & (1 << k)) { + if (i + 1 > macvlan->vlan_num) { + PMD_INIT_LOG(ERR, "vlan number " + "not match"); + fm10k_mbx_unlock(hw); + return; + } + fm10k_update_uc_addr(hw, + hw->mac.dglort_map, mac, + j * FM10K_UINT32_BIT_SIZE + k, + add, 0); + i++; + } + } + } + } + fm10k_mbx_unlock(hw); + + if (add) + macvlan->mac_num++; + else + macvlan->mac_num--; +} + +/* Add a MAC address, and update filters */ +static void +fm10k_macaddr_add(struct rte_eth_dev *dev, + struct ether_addr *mac_addr, + __rte_unused uint32_t index, + __rte_unused uint32_t pool) +{ + fm10k_MAC_filter_set(dev, mac_addr->addr_bytes, TRUE); +} + +/* Remove a MAC address, and update filters */ +static void +fm10k_macaddr_remove(struct rte_eth_dev *dev, uint32_t index) +{ + struct rte_eth_dev_data *data = dev->data; + + if (index < FM10K_MAX_MACADDR_NUM) + fm10k_MAC_filter_set(dev, data->mac_addrs[index].addr_bytes, + FALSE); +} + static inline int check_nb_desc(uint16_t min, uint16_t max, uint16_t mult, uint16_t request) { @@ -1728,6 +1801,8 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = { .link_update = fm10k_link_update, .dev_infos_get = fm10k_dev_infos_get, .vlan_filter_set = fm10k_vlan_filter_set, + .mac_addr_add = fm10k_macaddr_add, + .mac_addr_remove = fm10k_macaddr_remove, .rx_queue_start = fm10k_dev_rx_queue_start, .rx_queue_stop = fm10k_dev_rx_queue_stop, .tx_queue_start = fm10k_dev_tx_queue_start, @@ -1809,7 +1884,8 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev) } /* Initialize MAC address(es) */ - dev->data->mac_addrs = rte_zmalloc("fm10k", ETHER_ADDR_LEN, 0); + dev->data->mac_addrs = rte_zmalloc("fm10k", + ETHER_ADDR_LEN * FM10K_MAX_MACADDR_NUM, 0); if (dev->data->mac_addrs == NULL) { PMD_INIT_LOG(ERR, "Cannot allocate memory for MAC addresses"); return -ENOMEM;