[dpdk-dev] [PATCH v2 10/32] net/sfc: support promiscuous and all-multicast control
Andrew Rybchenko
arybchenko at solarflare.com
Thu Dec 15 13:51:01 CET 2016
From: Ivan Malov <ivan.malov at oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov at oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
Reviewed-by: Andrew Lee <alee at solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse at solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 2 ++
doc/guides/nics/sfc_efx.rst | 4 +++
drivers/net/sfc/sfc.h | 11 +++++++
drivers/net/sfc/sfc_ethdev.c | 57 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_port.c | 18 +++++++++++-
5 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 60ecca0..aaea993 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -9,6 +9,8 @@ Link status = Y
Link status event = Y
MTU update = Y
Jumbo frame = Y
+Promiscuous mode = Y
+Allmulticast mode = Y
Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index c482d77..984da9c 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -59,6 +59,10 @@ SFC EFX PMD has support for:
- Jumbo frames up to 9K
+- Promiscuous mode
+
+- Allmulticast mode
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index ff0bc3c..7b135e1 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -93,6 +93,13 @@ enum sfc_adapter_state {
SFC_ADAPTER_NSTATES
};
+enum sfc_dev_filter_mode {
+ SFC_DEV_FILTER_MODE_PROMISC = 0,
+ SFC_DEV_FILTER_MODE_ALLMULTI,
+
+ SFC_DEV_FILTER_NMODES
+};
+
enum sfc_mcdi_state {
SFC_MCDI_UNINITIALIZED = 0,
SFC_MCDI_INITIALIZED,
@@ -130,6 +137,9 @@ struct sfc_port {
boolean_t flow_ctrl_autoneg;
size_t pdu;
+ boolean_t promisc;
+ boolean_t allmulti;
+
rte_spinlock_t mac_stats_lock;
uint64_t *mac_stats_buf;
efsys_mem_t mac_stats_dma_mem;
@@ -249,6 +259,7 @@ void sfc_port_stop(struct sfc_adapter *sa);
void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
struct rte_eth_link *link_info);
int sfc_port_update_mac_stats(struct sfc_adapter *sa);
+int sfc_set_rx_mode(struct sfc_adapter *sa);
#ifdef __cplusplus
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 1716d78..c6095ad 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -253,6 +253,59 @@ sfc_dev_close(struct rte_eth_dev *dev)
sfc_log_init(sa, "done");
}
+static void
+sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode,
+ boolean_t enabled)
+{
+ struct sfc_port *port;
+ boolean_t *toggle;
+ struct sfc_adapter *sa = dev->data->dev_private;
+ boolean_t allmulti = (mode == SFC_DEV_FILTER_MODE_ALLMULTI);
+ const char *desc = (allmulti) ? "all-multi" : "promiscuous";
+
+ sfc_adapter_lock(sa);
+
+ port = &sa->port;
+ toggle = (allmulti) ? (&port->allmulti) : (&port->promisc);
+
+ if (*toggle != enabled) {
+ *toggle = enabled;
+
+ if ((sa->state == SFC_ADAPTER_STARTED) &&
+ (sfc_set_rx_mode(sa) != 0)) {
+ *toggle = !(enabled);
+ sfc_warn(sa, "Failed to %s %s mode",
+ ((enabled) ? "enable" : "disable"), desc);
+ }
+ }
+
+ sfc_adapter_unlock(sa);
+}
+
+static void
+sfc_dev_promisc_enable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_TRUE);
+}
+
+static void
+sfc_dev_promisc_disable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_FALSE);
+}
+
+static void
+sfc_dev_allmulti_enable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_ALLMULTI, B_TRUE);
+}
+
+static void
+sfc_dev_allmulti_disable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_ALLMULTI, B_FALSE);
+}
+
static int
sfc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
uint16_t nb_rx_desc, unsigned int socket_id,
@@ -661,6 +714,10 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_set_link_up = sfc_dev_set_link_up,
.dev_set_link_down = sfc_dev_set_link_down,
.dev_close = sfc_dev_close,
+ .promiscuous_enable = sfc_dev_promisc_enable,
+ .promiscuous_disable = sfc_dev_promisc_disable,
+ .allmulticast_enable = sfc_dev_allmulti_enable,
+ .allmulticast_disable = sfc_dev_allmulti_disable,
.link_update = sfc_dev_link_update,
.stats_get = sfc_stats_get,
.xstats_get = sfc_xstats_get,
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index 1241af7..dc6ecdf 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -103,7 +103,11 @@ sfc_port_start(struct sfc_adapter *sa)
goto fail_mac_addr_set;
sfc_log_init(sa, "set MAC filters");
- rc = efx_mac_filter_set(sa->nic, B_TRUE, B_TRUE, B_TRUE, B_TRUE);
+ port->promisc = (sa->eth_dev->data->promiscuous != 0) ?
+ B_TRUE : B_FALSE;
+ port->allmulti = (sa->eth_dev->data->all_multicast != 0) ?
+ B_TRUE : B_FALSE;
+ rc = sfc_set_rx_mode(sa);
if (rc != 0)
goto fail_mac_filter_set;
@@ -219,6 +223,18 @@ sfc_port_fini(struct sfc_adapter *sa)
sfc_log_init(sa, "done");
}
+int
+sfc_set_rx_mode(struct sfc_adapter *sa)
+{
+ struct sfc_port *port = &sa->port;
+ int rc;
+
+ rc = efx_mac_filter_set(sa->nic, port->promisc, B_TRUE,
+ port->promisc || port->allmulti, B_TRUE);
+
+ return rc;
+}
+
void
sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
struct rte_eth_link *link_info)
--
2.5.5
More information about the dev
mailing list