From patchwork Thu Mar 2 14:40:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 21131 X-Patchwork-Delegate: ferruh.yigit@amd.com 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 4F4D3322C; Thu, 2 Mar 2017 15:41:01 +0100 (CET) Received: from nbfkord-smmo03.seg.att.com (nbfkord-smmo03.seg.att.com [209.65.160.84]) by dpdk.org (Postfix) with ESMTP id 1B7B22C60; Thu, 2 Mar 2017 15:40:58 +0100 (CET) Received: from unknown [12.187.104.26] (EHLO webmail.solarflare.com) by nbfkord-smmo03.seg.att.com(mxl_mta-7.2.4-7) over TLS secured channel with ESMTP id afe28b85.0.5420249.00-2380.11931316.nbfkord-smmo03.seg.att.com (envelope-from ); Thu, 02 Mar 2017 14:40:59 +0000 (UTC) X-MXL-Hash: 58b82efb2565975d-56d2e3172035db2f11a17b3c1647cd604b9bcb47 Received: from ocex03.SolarFlarecom.com (10.20.40.36) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1044.25; Thu, 2 Mar 2017 06:40:56 -0800 Received: from opal.uk.solarflarecom.com (10.17.10.1) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1044.25 via Frontend Transport; Thu, 2 Mar 2017 06:40:55 -0800 Received: from uklogin.uk.solarflarecom.com (uklogin.uk.solarflarecom.com [10.17.10.10]) by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id v22EesM6031179; Thu, 2 Mar 2017 14:40:54 GMT Received: from uklogin.uk.solarflarecom.com (localhost.localdomain [127.0.0.1]) by uklogin.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id v22EescD027393; Thu, 2 Mar 2017 14:40:54 GMT From: Andrew Rybchenko To: CC: Ivan Malov , Date: Thu, 2 Mar 2017 14:40:48 +0000 Message-ID: <1488465648-27351-1-git-send-email-arybchenko@solarflare.com> X-Mailer: git-send-email 1.8.2.3 MIME-Version: 1.0 X-AnalysisOut: [v=2.1 cv=HuVwbhnS c=1 sm=1 tr=0 a=8BlWFWvVlq5taO8ncb8nKg==] X-AnalysisOut: [:17 a=6Iz7jQTuP9IA:10 a=pK7X0mNQAAAA:8 a=8rWy6zfcAAAA:8 a=] X-AnalysisOut: [zRKbQ67AAAAA:8 a=kFop9xxnPcyAYQgT1Q8A:9 a=xWOY-RmOwDhfmARW] X-AnalysisOut: [:21 a=OrpLX1hpQK7_vp6Z:21 a=5HA-qpC1VU4iIGLgRoNS:22 a=YjdV] X-AnalysisOut: [zJdQTyZRADMV7wFX:22 a=PA03WX8tBzeizutn5_OT:22] X-Spam: [F=0.4886477202; CM=0.500; S=0.488(2015072901)] X-MAIL-FROM: X-SOURCE-IP: [12.187.104.26] Subject: [dpdk-dev] [PATCH] net/sfc: set multicast address list in started state only X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Ivan Malov According to 'libefx' API requirements, one is allowed to apply multicast address list to the port in started state only, otherwise the new array should be copied to a local storage in order to be applied during the next port start Fixes: 0fa0070e4391 ("net/sfc: support multicast addresses list controls") Coverity issue: 141296 Fixes: e9ddf37a507d ("net/sfc: fix setting empty multicast list") Cc: stable@dpdk.org Signed-off-by: Ivan Malov Signed-off-by: Andrew Rybchenko Reviewed-by: Andrew Lee Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc.h | 4 ++++ drivers/net/sfc/sfc_ethdev.c | 35 ++++++++++++++++------------------- drivers/net/sfc/sfc_port.c | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 8c6c02f..d1fc84b 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -150,6 +150,10 @@ struct sfc_port { boolean_t promisc; boolean_t allmulti; + unsigned int max_mcast_addrs; + unsigned int nb_mcast_addrs; + uint8_t *mcast_addrs; + rte_spinlock_t mac_stats_lock; uint64_t *mac_stats_buf; efsys_mem_t mac_stats_dma_mem; diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 71587fb..5ff1cc1 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -805,36 +805,33 @@ sfc_set_mc_addr_list(struct rte_eth_dev *dev, struct ether_addr *mc_addr_set, uint32_t nb_mc_addr) { struct sfc_adapter *sa = dev->data->dev_private; - uint8_t *mc_addrs_p = NULL; + struct sfc_port *port = &sa->port; + uint8_t *mc_addrs = port->mcast_addrs; int rc; unsigned int i; - if (nb_mc_addr > EFX_MAC_MULTICAST_LIST_MAX) { + if (mc_addrs == NULL) + return -ENOBUFS; + + if (nb_mc_addr > port->max_mcast_addrs) { sfc_err(sa, "too many multicast addresses: %u > %u", - nb_mc_addr, EFX_MAC_MULTICAST_LIST_MAX); + nb_mc_addr, port->max_mcast_addrs); return -EINVAL; } - if (nb_mc_addr != 0) { - uint8_t *mc_addrs; - - mc_addrs_p = rte_calloc("mc-addrs", nb_mc_addr, - EFX_MAC_ADDR_LEN, 0); - if (mc_addrs_p == NULL) - return -ENOMEM; - - mc_addrs = mc_addrs_p; - for (i = 0; i < nb_mc_addr; ++i) { - (void)rte_memcpy(mc_addrs, mc_addr_set[i].addr_bytes, - EFX_MAC_ADDR_LEN); - mc_addrs += EFX_MAC_ADDR_LEN; - } + for (i = 0; i < nb_mc_addr; ++i) { + (void)rte_memcpy(mc_addrs, mc_addr_set[i].addr_bytes, + EFX_MAC_ADDR_LEN); + mc_addrs += EFX_MAC_ADDR_LEN; } - rc = efx_mac_multicast_list_set(sa->nic, mc_addrs_p, nb_mc_addr); + port->nb_mcast_addrs = nb_mc_addr; - rte_free(mc_addrs_p); + if (sa->state != SFC_ADAPTER_STARTED) + return 0; + rc = efx_mac_multicast_list_set(sa->nic, port->mcast_addrs, + port->nb_mcast_addrs); if (rc != 0) sfc_err(sa, "cannot set multicast address list (rc = %u)", rc); diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c index 5998a99..507df01 100644 --- a/drivers/net/sfc/sfc_port.c +++ b/drivers/net/sfc/sfc_port.c @@ -140,6 +140,12 @@ sfc_port_start(struct sfc_adapter *sa) if (rc != 0) goto fail_mac_filter_set; + sfc_log_init(sa, "set multicast address list"); + rc = efx_mac_multicast_list_set(sa->nic, port->mcast_addrs, + port->nb_mcast_addrs); + if (rc != 0) + goto fail_mcast_address_list_set; + efx_mac_stats_get_mask(sa->nic, port->mac_stats_mask, sizeof(port->mac_stats_mask)); @@ -174,6 +180,7 @@ sfc_port_start(struct sfc_adapter *sa) 0, B_FALSE); fail_mac_stats_periodic: +fail_mcast_address_list_set: fail_mac_filter_set: fail_mac_addr_set: fail_mac_pdu_set: @@ -223,6 +230,17 @@ sfc_port_init(struct sfc_adapter *sa) else port->pdu = EFX_MAC_PDU(dev_data->mtu); + port->max_mcast_addrs = EFX_MAC_MULTICAST_LIST_MAX; + port->nb_mcast_addrs = 0; + port->mcast_addrs = rte_calloc_socket("mcast_addr_list_buf", + port->max_mcast_addrs, + EFX_MAC_ADDR_LEN, 0, + sa->socket_id); + if (port->mcast_addrs == NULL) { + rc = ENOMEM; + goto fail_mcast_addr_list_buf_alloc; + } + rte_spinlock_init(&port->mac_stats_lock); rc = ENOMEM; @@ -243,6 +261,7 @@ sfc_port_init(struct sfc_adapter *sa) fail_mac_stats_dma_alloc: rte_free(port->mac_stats_buf); fail_mac_stats_buf_alloc: +fail_mcast_addr_list_buf_alloc: sfc_log_init(sa, "failed %d", rc); return rc; }