X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fsfc_port.c;h=4de13267d5f727d467b98a72b4985ad7c96becc0;hb=ec12dc5a554ab4f8dd8a90cab54426dfa685ba80;hp=5cc3ad7bd69af0be66c230363390b88baa5cf6be;hpb=b16cf4b27fe4c02fc3609485bdcf0f5643f2f609;p=dpdk.git diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c index 5cc3ad7bd6..4de13267d5 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-2020 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" @@ -87,6 +88,18 @@ sfc_port_update_mac_stats(struct sfc_adapter *sa) return 0; } +static void +sfc_port_reset_sw_stats(struct sfc_adapter *sa) +{ + struct sfc_port *port = &sa->port; + + /* + * Reset diff stats explicitly since check which does not allow + * the statistics to grow backward could deny it. + */ + port->ipackets = 0; +} + int sfc_port_reset_mac_stats(struct sfc_adapter *sa) { @@ -95,6 +108,8 @@ sfc_port_reset_mac_stats(struct sfc_adapter *sa) rte_spinlock_lock(&port->mac_stats_lock); rc = efx_mac_stats_clear(sa->nic); + if (rc == 0) + sfc_port_reset_sw_stats(sa); rte_spinlock_unlock(&port->mac_stats_lock); return rc; @@ -192,6 +207,16 @@ sfc_port_start(struct sfc_adapter *sa) SFC_ASSERT((port->phy_adv_cap & phy_pause_caps) == 0); phy_adv_cap = port->phy_adv_cap | (phy_adv_cap & phy_pause_caps); + /* + * No controls for FEC yet. Use default FEC mode. + * I.e. advertise everything supported (*_FEC=1), but do not request + * anything explicitly (*_FEC_REQUESTED=0). + */ + phy_adv_cap |= port->phy_adv_cap_mask & + (1u << EFX_PHY_CAP_BASER_FEC | + 1u << EFX_PHY_CAP_RS_FEC | + 1u << EFX_PHY_CAP_25G_BASER_FEC); + sfc_log_init(sa, "set phy adv caps to %#x", phy_adv_cap); rc = efx_phy_adv_cap_set(sa->nic, phy_adv_cap); if (rc != 0) @@ -202,8 +227,8 @@ sfc_port_start(struct sfc_adapter *sa) if (rc != 0) goto fail_mac_pdu_set; - if (!port->isolated) { - struct ether_addr *addr = &port->default_mac_addr; + if (!sfc_sa2shared(sa)->isolated) { + struct rte_ether_addr *addr = &port->default_mac_addr; sfc_log_init(sa, "set MAC address"); rc = efx_mac_addr_set(sa->nic, addr->addr_bytes); @@ -215,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; @@ -362,7 +387,7 @@ sfc_port_attach(struct sfc_adapter *sa) { struct sfc_port *port = &sa->port; const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); - const struct ether_addr *from; + const struct rte_ether_addr *from; uint32_t mac_nstats; size_t mac_stats_size; long kvarg_stats_update_period_ms; @@ -377,8 +402,8 @@ sfc_port_attach(struct sfc_adapter *sa) port->flow_ctrl_autoneg = B_TRUE; RTE_BUILD_BUG_ON(sizeof(encp->enc_mac_addr) != sizeof(*from)); - from = (const struct ether_addr *)(encp->enc_mac_addr); - ether_addr_copy(from, &port->default_mac_addr); + from = (const struct rte_ether_addr *)(encp->enc_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; @@ -461,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