net/sfc: support promiscuous and all-multicast control
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> Reviewed-by: Andrew Lee <alee@solarflare.com> Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
This commit is contained in:
parent
2a05f337ce
commit
f3de384044
@ -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
|
||||
|
@ -59,6 +59,10 @@ SFC EFX PMD has support for:
|
||||
|
||||
- Jumbo frames up to 9K
|
||||
|
||||
- Promiscuous mode
|
||||
|
||||
- Allmulticast mode
|
||||
|
||||
|
||||
Non-supported Features
|
||||
----------------------
|
||||
|
@ -96,6 +96,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,
|
||||
@ -133,6 +140,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;
|
||||
@ -252,6 +262,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
|
||||
|
@ -252,6 +252,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,
|
||||
@ -660,6 +713,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,
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user