/* 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.
return 0;
}
-static void
+static int
sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
+
+ return 0;
}
static const uint32_t *
free(sa);
}
-static void
+static int
sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode,
boolean_t enabled)
{
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
boolean_t allmulti = (mode == SFC_DEV_FILTER_MODE_ALLMULTI);
const char *desc = (allmulti) ? "all-multi" : "promiscuous";
+ int rc = 0;
sfc_adapter_lock(sa);
"start provided that isolated mode is "
"disabled prior the next start");
} else if ((sa->state == SFC_ADAPTER_STARTED) &&
- (sfc_set_rx_mode(sa) != 0)) {
+ ((rc = sfc_set_rx_mode(sa)) != 0)) {
*toggle = !(enabled);
- sfc_warn(sa, "Failed to %s %s mode",
- ((enabled) ? "enable" : "disable"), desc);
+ sfc_warn(sa, "Failed to %s %s mode, rc = %d",
+ ((enabled) ? "enable" : "disable"), desc, rc);
+
+ /*
+ * For promiscuous and all-multicast filters a
+ * permission failure should be reported as an
+ * unsupported filter.
+ */
+ if (rc == EPERM)
+ rc = ENOTSUP;
}
}
sfc_adapter_unlock(sa);
+ return rc;
}
-static void
+static int
sfc_dev_promisc_enable(struct rte_eth_dev *dev)
{
- sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_TRUE);
+ int rc = sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_TRUE);
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
}
-static void
+static int
sfc_dev_promisc_disable(struct rte_eth_dev *dev)
{
- sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_FALSE);
+ int rc = sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_FALSE);
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
}
-static void
+static int
sfc_dev_allmulti_enable(struct rte_eth_dev *dev)
{
- sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_ALLMULTI, B_TRUE);
+ int rc = sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_ALLMULTI, B_TRUE);
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
}
-static void
+static int
sfc_dev_allmulti_disable(struct rte_eth_dev *dev)
{
- sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_ALLMULTI, B_FALSE);
+ int rc = sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_ALLMULTI, B_FALSE);
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
}
static int
return -ret;
}
-static void
+static int
sfc_stats_reset(struct rte_eth_dev *dev)
{
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
* will be scheduled to be done during the next port start
*/
port->mac_stats_reset_pending = B_TRUE;
- return;
+ return 0;
}
rc = sfc_port_reset_mac_stats(sa);
if (rc != 0)
sfc_err(sa, "failed to reset statistics (rc = %d)", rc);
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
}
static int
sfc_adapter_lock(sa);
+ if (rte_is_same_ether_addr(mac_addr, &port->default_mac_addr))
+ goto unlock;
+
/*
* Copy the address to the device private data so that
* it could be recalled in the case of adapter restart.
* has no effect on received traffic, therefore
* we also need to update unicast filters
*/
- rc = sfc_set_rx_mode(sa);
+ rc = sfc_set_rx_mode_unchecked(sa);
if (rc != 0) {
sfc_err(sa, "cannot set filter (rc = %u)", rc);
/* Rollback the old address */
(void)efx_mac_addr_set(sa->nic, old_addr->addr_bytes);
- (void)sfc_set_rx_mode(sa);
+ (void)sfc_set_rx_mode_unchecked(sa);
}
} else {
sfc_warn(sa, "cannot set MAC address with filters installed");
if ((rss_conf->rss_key != NULL) &&
(rss_conf->rss_key_len != sizeof(rss->key))) {
- sfc_err(sa, "RSS key size is wrong (should be %lu)",
+ sfc_err(sa, "RSS key size is wrong (should be %zu)",
sizeof(rss->key));
return -EINVAL;
}