From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 6BCB22BA5 for ; Wed, 9 Mar 2016 09:22:56 +0100 (CET) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP; 09 Mar 2016 00:22:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,310,1455004800"; d="scan'208";a="920006463" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga001.fm.intel.com with ESMTP; 09 Mar 2016 00:22:54 -0800 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id u298MqIL018187; Wed, 9 Mar 2016 16:22:52 +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 u298MmeL009271; Wed, 9 Mar 2016 16:22:50 +0800 Received: (from wujingji@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id u298MmuH009267; Wed, 9 Mar 2016 16:22:48 +0800 From: Jingjing Wu To: bruce.richardson@intel.com Date: Wed, 9 Mar 2016 16:22:46 +0800 Message-Id: <1457511766-9237-1-git-send-email-jingjing.wu@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1453424966-5678-1-git-send-email-jingjing.wu@intel.com> References: <1453424966-5678-1-git-send-email-jingjing.wu@intel.com> Cc: dev@dpdk.org Subject: [dpdk-dev] [PATCH v2] i40evf: enable ops to set mac address 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: Wed, 09 Mar 2016 08:22:57 -0000 This patch implemented the ops of adding and removing mac address in i40evf driver. Functions are assigned like: .mac_addr_add = i40evf_add_mac_addr, .mac_addr_remove = i40evf_del_mac_addr, To support multiple mac addresses setting, this patch also extended the mac addresses adding and deletion when device start and stop. For each VF, 64 mac addresses can be added to in maximum. Signed-off-by: Jingjing Wu Acked-by: Zhe Tao --- v2 change: - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2) doc/guides/rel_notes/release_16_04.rst | 2 + drivers/net/i40e/i40e_ethdev.c | 2 - drivers/net/i40e/i40e_ethdev.h | 3 + drivers/net/i40e/i40e_ethdev_vf.c | 123 +++++++++++++++++++++++++-------- 4 files changed, 98 insertions(+), 32 deletions(-) diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst index eab5f92..e019669 100644 --- a/doc/guides/rel_notes/release_16_04.rst +++ b/doc/guides/rel_notes/release_16_04.rst @@ -105,6 +105,8 @@ This section should contain new features added in this release. Sample format: be down. We added the support of auto-neg by SW to avoid this link down issue. +* **Added i40e VF mac address setting support.** + Resolved Issues --------------- diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 0c87ec1..49222f4 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -62,8 +62,6 @@ #include "i40e_rxtx.h" #include "i40e_pf.h" -/* Maximun number of MAC addresses */ -#define I40E_NUM_MACADDR_MAX 64 #define I40E_CLEAR_PXE_WAIT_MS 200 /* Maximun number of capability elements */ diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index a9b805e..237a42c 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -53,6 +53,9 @@ #define I40E_DEFAULT_QP_NUM_FDIR 1 #define I40E_UINT32_BIT_SIZE (CHAR_BIT * sizeof(uint32_t)) #define I40E_VFTA_SIZE (4096 / I40E_UINT32_BIT_SIZE) +/* Maximun number of MAC addresses */ +#define I40E_NUM_MACADDR_MAX 64 + /* * vlan_id is a 12 bit number. * The VFTA array is actually a 4096 bit array, 128 of 32bit elements. diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 6185ee8..6b7b350 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -139,6 +139,11 @@ static int i40evf_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id); static int i40evf_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id); +static void i40evf_add_mac_addr(struct rte_eth_dev *dev, + struct ether_addr *addr, + uint32_t index, + uint32_t pool); +static void i40evf_del_mac_addr(struct rte_eth_dev *dev, uint32_t index); static int i40evf_dev_rss_reta_update(struct rte_eth_dev *dev, struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size); @@ -210,6 +215,8 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = { .rx_descriptor_done = i40e_dev_rx_descriptor_done, .tx_queue_setup = i40e_dev_tx_queue_setup, .tx_queue_release = i40e_dev_tx_queue_release, + .mac_addr_add = i40evf_add_mac_addr, + .mac_addr_remove = i40evf_del_mac_addr, .reta_update = i40evf_dev_rss_reta_update, .reta_query = i40evf_dev_rss_reta_query, .rss_hash_update = i40evf_dev_rss_hash_update, @@ -855,8 +862,11 @@ i40evf_stop_queues(struct rte_eth_dev *dev) return 0; } -static int -i40evf_add_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr) +static void +i40evf_add_mac_addr(struct rte_eth_dev *dev, + struct ether_addr *addr, + __rte_unused uint32_t index, + __rte_unused uint32_t pool) { struct i40e_virtchnl_ether_addr_list *list; struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); @@ -870,7 +880,7 @@ i40evf_add_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr) addr->addr_bytes[0], addr->addr_bytes[1], addr->addr_bytes[2], addr->addr_bytes[3], addr->addr_bytes[4], addr->addr_bytes[5]); - return -1; + return; } list = (struct i40e_virtchnl_ether_addr_list *)cmd_buffer; @@ -889,25 +899,29 @@ i40evf_add_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr) PMD_DRV_LOG(ERR, "fail to execute command " "OP_ADD_ETHER_ADDRESS"); - return err; + return; } -static int -i40evf_del_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr) +static void +i40evf_del_mac_addr(struct rte_eth_dev *dev, uint32_t index) { struct i40e_virtchnl_ether_addr_list *list; struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); + struct rte_eth_dev_data *data = dev->data; + struct ether_addr *addr; uint8_t cmd_buffer[sizeof(struct i40e_virtchnl_ether_addr_list) + \ sizeof(struct i40e_virtchnl_ether_addr)]; int err; struct vf_cmd_info args; + addr = &(data->mac_addrs[index]); + if (i40e_validate_mac_addr(addr->addr_bytes) != I40E_SUCCESS) { PMD_DRV_LOG(ERR, "Invalid mac:%x-%x-%x-%x-%x-%x", addr->addr_bytes[0], addr->addr_bytes[1], addr->addr_bytes[2], addr->addr_bytes[3], addr->addr_bytes[4], addr->addr_bytes[5]); - return -1; + return; } list = (struct i40e_virtchnl_ether_addr_list *)cmd_buffer; @@ -925,8 +939,7 @@ i40evf_del_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr) if (err) PMD_DRV_LOG(ERR, "fail to execute command " "OP_DEL_ETHER_ADDRESS"); - - return err; + return; } static int @@ -1302,16 +1315,18 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev) return -1; } - /* copy mac addr */ + /* allocate memory for mac addr storage */ eth_dev->data->mac_addrs = rte_zmalloc("i40evf_mac", - ETHER_ADDR_LEN, 0); + ETHER_ADDR_LEN * I40E_NUM_MACADDR_MAX, + 0); if (eth_dev->data->mac_addrs == NULL) { - PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to " - "store MAC addresses", ETHER_ADDR_LEN); + PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to" + " store MAC addresses", + ETHER_ADDR_LEN * I40E_NUM_MACADDR_MAX); return -ENOMEM; } ether_addr_copy((struct ether_addr *)hw->mac.addr, - (struct ether_addr *)eth_dev->data->mac_addrs); + ð_dev->data->mac_addrs[0]); return 0; } @@ -1778,13 +1793,69 @@ i40evf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id) return 0; } +static void +i40evf_add_del_all_mac_addr(struct rte_eth_dev *dev, bool add) +{ + struct i40e_virtchnl_ether_addr_list *list; + struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); + int err, i, j; + int next_begin = 0; + int begin = 0; + uint32_t len; + struct ether_addr *addr; + struct vf_cmd_info args; + + do { + j = 0; + len = sizeof(struct i40e_virtchnl_ether_addr_list); + for (i = begin; i < I40E_NUM_MACADDR_MAX; i++, next_begin++) { + if (is_zero_ether_addr(&dev->data->mac_addrs[i])) + continue; + len += sizeof(struct i40e_virtchnl_ether_addr); + if (len >= I40E_AQ_BUF_SZ) { + next_begin = i + 1; + break; + } + } + + list = rte_zmalloc("i40evf_del_mac_buffer", len, 0); + + for (i = begin; i < next_begin; i++) { + addr = &dev->data->mac_addrs[i]; + if (is_zero_ether_addr(addr)) + continue; + (void)rte_memcpy(list->list[j].addr, addr->addr_bytes, + sizeof(addr->addr_bytes)); + PMD_DRV_LOG(DEBUG, "add/rm mac:%x:%x:%x:%x:%x:%x", + addr->addr_bytes[0], addr->addr_bytes[1], + addr->addr_bytes[2], addr->addr_bytes[3], + addr->addr_bytes[4], addr->addr_bytes[5]); + j++; + } + list->vsi_id = vf->vsi_res->vsi_id; + list->num_elements = j; + args.ops = add ? I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS : + I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS; + args.in_args = (uint8_t *)list; + args.in_args_size = len; + args.out_buffer = cmd_result_buffer; + args.out_size = I40E_AQ_BUF_SZ; + err = i40evf_execute_vf_cmd(dev, &args); + if (err) + PMD_DRV_LOG(ERR, "fail to execute command %s", + add ? "OP_ADD_ETHER_ADDRESS" : + "OP_DEL_ETHER_ADDRESS"); + rte_free(list); + begin = next_begin; + } while (begin < I40E_NUM_MACADDR_MAX); +} + static int i40evf_dev_start(struct rte_eth_dev *dev) { struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle; - struct ether_addr mac_addr; uint32_t intr_vector = 0; PMD_INIT_FUNC_TRACE(); @@ -1829,13 +1900,8 @@ i40evf_dev_start(struct rte_eth_dev *dev) goto err_queue; } - /* Set mac addr */ - (void)rte_memcpy(mac_addr.addr_bytes, hw->mac.addr, - sizeof(mac_addr.addr_bytes)); - if (i40evf_add_mac_addr(dev, &mac_addr)) { - PMD_DRV_LOG(ERR, "Failed to add mac addr"); - goto err_queue; - } + /* Set all mac addrs */ + i40evf_add_del_all_mac_addr(dev, TRUE); if (i40evf_start_queues(dev) != 0) { PMD_DRV_LOG(ERR, "enable queues failed"); @@ -1850,7 +1916,7 @@ i40evf_dev_start(struct rte_eth_dev *dev) return 0; err_mac: - i40evf_del_mac_addr(dev, &mac_addr); + i40evf_add_del_all_mac_addr(dev, FALSE); err_queue: return -1; } @@ -1858,9 +1924,7 @@ err_queue: static void i40evf_dev_stop(struct rte_eth_dev *dev) { - struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle; - struct ether_addr mac_addr; PMD_INIT_FUNC_TRACE(); @@ -1874,11 +1938,9 @@ i40evf_dev_stop(struct rte_eth_dev *dev) rte_free(intr_handle->intr_vec); intr_handle->intr_vec = NULL; } - /* Set mac addr */ - (void)rte_memcpy(mac_addr.addr_bytes, hw->mac.addr, - sizeof(mac_addr.addr_bytes)); - /* Delete mac addr of this vf */ - i40evf_del_mac_addr(dev, &mac_addr); + /* remove all mac addrs */ + i40evf_add_del_all_mac_addr(dev, FALSE); + } static int @@ -1977,6 +2039,7 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->hash_key_size = (I40E_VFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t); dev_info->reta_size = ETH_RSS_RETA_SIZE_64; dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL; + dev_info->max_mac_addrs = I40E_NUM_MACADDR_MAX; dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP | DEV_RX_OFFLOAD_QINQ_STRIP | -- 2.4.0