X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fsfc_port.c;h=ac117f9c48144af23ba8680c13ee091449a17fd8;hb=95e7bb6a5fc9e371e763b11ec15786e4d574ef8e;hp=8de5f0c60c0b5cfdc36d1e31b486ed00fbd26b96;hpb=6d13ea8e8e49ab957deae2bba5ecf4a4bfe747d1;p=dpdk.git diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c index 8de5f0c60c..ac117f9c48 100644 --- a/drivers/net/sfc/sfc_port.c +++ b/drivers/net/sfc/sfc_port.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright (c) 2016-2018 Solarflare Communications Inc. - * All rights reserved. + * Copyright(c) 2019-2021 Xilinx, Inc. + * Copyright(c) 2016-2019 Solarflare Communications Inc. * * This software was jointly developed between OKTET Labs (under contract * for Solarflare) and Solarflare Communications, Inc. @@ -10,6 +10,7 @@ #include "efx.h" #include "sfc.h" +#include "sfc_debug.h" #include "sfc_log.h" #include "sfc_kvargs.h" @@ -239,7 +240,7 @@ sfc_port_start(struct sfc_adapter *sa) B_TRUE : B_FALSE; port->allmulti = (sa->eth_dev->data->all_multicast != 0) ? B_TRUE : B_FALSE; - rc = sfc_set_rx_mode(sa); + rc = sfc_set_rx_mode_unchecked(sa); if (rc != 0) goto fail_mac_filter_set; @@ -402,7 +403,7 @@ sfc_port_attach(struct sfc_adapter *sa) RTE_BUILD_BUG_ON(sizeof(encp->enc_mac_addr) != sizeof(*from)); from = (const struct rte_ether_addr *)(encp->enc_mac_addr); - ether_addr_copy(from, &port->default_mac_addr); + rte_ether_addr_copy(from, &port->default_mac_addr); port->max_mcast_addrs = EFX_MAC_MULTICAST_LIST_MAX; port->nb_mcast_addrs = 0; @@ -485,16 +486,70 @@ sfc_port_detach(struct sfc_adapter *sa) sfc_log_init(sa, "done"); } +static boolean_t +sfc_get_requested_all_ucast(struct sfc_port *port) +{ + return port->promisc; +} + +static boolean_t +sfc_get_requested_all_mcast(struct sfc_port *port) +{ + return port->promisc || port->allmulti; +} + +int +sfc_set_rx_mode_unchecked(struct sfc_adapter *sa) +{ + struct sfc_port *port = &sa->port; + boolean_t requested_all_ucast = sfc_get_requested_all_ucast(port); + boolean_t requested_all_mcast = sfc_get_requested_all_mcast(port); + int rc; + + rc = efx_mac_filter_set(sa->nic, requested_all_ucast, B_TRUE, + requested_all_mcast, B_TRUE); + if (rc != 0) + return rc; + + return 0; +} + int sfc_set_rx_mode(struct sfc_adapter *sa) { struct sfc_port *port = &sa->port; + boolean_t old_all_ucast; + boolean_t old_all_mcast; + boolean_t requested_all_ucast = sfc_get_requested_all_ucast(port); + boolean_t requested_all_mcast = sfc_get_requested_all_mcast(port); + boolean_t actual_all_ucast; + boolean_t actual_all_mcast; int rc; - rc = efx_mac_filter_set(sa->nic, port->promisc, B_TRUE, - port->promisc || port->allmulti, B_TRUE); + efx_mac_filter_get_all_ucast_mcast(sa->nic, &old_all_ucast, + &old_all_mcast); - return rc; + rc = sfc_set_rx_mode_unchecked(sa); + if (rc != 0) + return rc; + + efx_mac_filter_get_all_ucast_mcast(sa->nic, &actual_all_ucast, + &actual_all_mcast); + + if (actual_all_ucast != requested_all_ucast || + actual_all_mcast != requested_all_mcast) { + /* + * MAC filter set succeeded but not all requested modes + * were applied. The rollback is necessary to bring back the + * consistent old state. + */ + (void)efx_mac_filter_set(sa->nic, old_all_ucast, B_TRUE, + old_all_mcast, B_TRUE); + + return EPERM; + } + + return 0; } void