From 05e4c3aff35f41d527acfab86df55477fd8dcff2 Mon Sep 17 00:00:00 2001 From: Wei Zhao Date: Mon, 13 Jul 2020 15:48:11 +0800 Subject: [PATCH] net/iavf: support multicast configuration This patch enable add multicast address for iavf. Signed-off-by: Wei Zhao Acked-by: Qi Zhang --- doc/guides/nics/features/iavf.ini | 1 + drivers/net/iavf/iavf.h | 7 ++++ drivers/net/iavf/iavf_ethdev.c | 43 ++++++++++++++++++++++++ drivers/net/iavf/iavf_vchnl.c | 56 +++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini index 2e7cea38d8..17f7928eb1 100644 --- a/doc/guides/nics/features/iavf.ini +++ b/doc/guides/nics/features/iavf.ini @@ -15,6 +15,7 @@ TSO = Y Promiscuous mode = Y Allmulticast mode = Y Unicast MAC filter = Y +Multicast MAC filter = Y RSS hash = Y RSS key update = Y RSS reta update = Y diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h index 9be8a23816..9ad331ee92 100644 --- a/drivers/net/iavf/iavf.h +++ b/drivers/net/iavf/iavf.h @@ -129,6 +129,10 @@ struct iavf_info { bool link_up; uint32_t link_speed; + /* Multicast addrs */ + struct rte_ether_addr mc_addrs[IAVF_NUM_MACADDR_MAX]; + uint16_t mc_addrs_num; /* Multicast mac addresses number */ + struct iavf_vsi vsi; bool vf_reset; uint64_t flags; @@ -272,4 +276,7 @@ int iavf_fdir_check(struct iavf_adapter *adapter, struct iavf_fdir_conf *filter); int iavf_add_del_rss_cfg(struct iavf_adapter *adapter, struct virtchnl_rss_cfg *rss_cfg, bool add); +int iavf_add_del_mc_addr_list(struct iavf_adapter *adapter, + struct rte_ether_addr *mc_addrs, + uint32_t mc_addrs_num, bool add); #endif /* _IAVF_ETHDEV_H_ */ diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c index c3aa4cd725..ae1ed58747 100644 --- a/drivers/net/iavf/iavf_ethdev.c +++ b/drivers/net/iavf/iavf_ethdev.c @@ -73,6 +73,9 @@ static int iavf_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type, enum rte_filter_op filter_op, void *arg); +static int iavf_set_mc_addr_list(struct rte_eth_dev *dev, + struct rte_ether_addr *mc_addrs, + uint32_t mc_addrs_num); static const struct rte_pci_id pci_id_iavf_map[] = { { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_ADAPTIVE_VF) }, @@ -96,6 +99,7 @@ static const struct eth_dev_ops iavf_eth_dev_ops = { .allmulticast_disable = iavf_dev_allmulticast_disable, .mac_addr_add = iavf_dev_add_mac_addr, .mac_addr_remove = iavf_dev_del_mac_addr, + .set_mc_addr_list = iavf_set_mc_addr_list, .vlan_filter_set = iavf_dev_vlan_filter_set, .vlan_offload_set = iavf_dev_vlan_offload_set, .rx_queue_start = iavf_dev_rx_queue_start, @@ -122,6 +126,35 @@ static const struct eth_dev_ops iavf_eth_dev_ops = { .filter_ctrl = iavf_dev_filter_ctrl, }; +static int +iavf_set_mc_addr_list(struct rte_eth_dev *dev, + struct rte_ether_addr *mc_addrs, + uint32_t mc_addrs_num) +{ + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); + struct iavf_adapter *adapter = + IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + int err; + + /* flush previous addresses */ + err = iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num, + false); + if (err) + return err; + + vf->mc_addrs_num = 0; + + /* add new ones */ + err = iavf_add_del_mc_addr_list(adapter, mc_addrs, mc_addrs_num, true); + if (err) + return err; + + vf->mc_addrs_num = mc_addrs_num; + memcpy(vf->mc_addrs, mc_addrs, mc_addrs_num * sizeof(*mc_addrs)); + + return 0; +} + static int iavf_init_rss(struct iavf_adapter *adapter) { @@ -451,6 +484,10 @@ iavf_dev_start(struct rte_eth_dev *dev) /* Set all mac addrs */ iavf_add_del_all_mac_addr(adapter, true); + /* Set all multicast addresses */ + iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num, + true); + if (iavf_start_queues(dev) != 0) { PMD_DRV_LOG(ERR, "enable queues failed"); goto err_mac; @@ -467,6 +504,7 @@ err_queue: static void iavf_dev_stop(struct rte_eth_dev *dev) { + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); struct iavf_adapter *adapter = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); struct rte_intr_handle *intr_handle = dev->intr_handle; @@ -488,6 +526,11 @@ iavf_dev_stop(struct rte_eth_dev *dev) /* remove all mac addrs */ iavf_add_del_all_mac_addr(adapter, false); + + /* remove all multicast addresses */ + iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num, + false); + adapter->stopped = 1; } diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c index 33acea54a5..6b57ecbbab 100644 --- a/drivers/net/iavf/iavf_vchnl.c +++ b/drivers/net/iavf/iavf_vchnl.c @@ -1075,3 +1075,59 @@ iavf_add_del_rss_cfg(struct iavf_adapter *adapter, return err; } + +int +iavf_add_del_mc_addr_list(struct iavf_adapter *adapter, + struct rte_ether_addr *mc_addrs, + uint32_t mc_addrs_num, bool add) +{ + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); + uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) + + (IAVF_NUM_MACADDR_MAX * sizeof(struct virtchnl_ether_addr))]; + struct virtchnl_ether_addr_list *list; + struct iavf_cmd_info args; + uint32_t i; + int err; + + if (mc_addrs == NULL || mc_addrs_num == 0) + return 0; + + if (mc_addrs_num > IAVF_NUM_MACADDR_MAX) + return -EINVAL; + + list = (struct virtchnl_ether_addr_list *)cmd_buffer; + list->vsi_id = vf->vsi_res->vsi_id; + list->num_elements = mc_addrs_num; + + for (i = 0; i < mc_addrs_num; i++) { + if (!IAVF_IS_MULTICAST(mc_addrs[i].addr_bytes)) { + PMD_DRV_LOG(ERR, "Invalid mac:%x:%x:%x:%x:%x:%x", + mc_addrs[i].addr_bytes[0], + mc_addrs[i].addr_bytes[1], + mc_addrs[i].addr_bytes[2], + mc_addrs[i].addr_bytes[3], + mc_addrs[i].addr_bytes[4], + mc_addrs[i].addr_bytes[5]); + return -EINVAL; + } + + memcpy(list->list[i].addr, mc_addrs[i].addr_bytes, + sizeof(list->list[i].addr)); + } + + args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR; + args.in_args = cmd_buffer; + args.in_args_size = sizeof(struct virtchnl_ether_addr_list) + + i * sizeof(struct virtchnl_ether_addr); + args.out_buffer = vf->aq_resp; + args.out_size = IAVF_AQ_BUF_SZ; + err = iavf_execute_vf_cmd(adapter, &args); + + if (err) { + PMD_DRV_LOG(ERR, "fail to execute command %s", + add ? "OP_ADD_ETH_ADDR" : "OP_DEL_ETH_ADDR"); + return err; + } + + return 0; +} -- 2.20.1