net/sfc: support flow API isolated mode
authorIvan Malov <ivan.malov@oktetlabs.ru>
Tue, 20 Jun 2017 16:37:09 +0000 (17:37 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 6 Jul 2017 13:00:56 +0000 (15:00 +0200)
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
drivers/net/sfc/sfc.h
drivers/net/sfc/sfc_ethdev.c
drivers/net/sfc/sfc_flow.c
drivers/net/sfc/sfc_port.c
drivers/net/sfc/sfc_rx.c

index 007ed24..d287413 100644 (file)
@@ -150,6 +150,11 @@ struct sfc_port {
        boolean_t                       flow_ctrl_autoneg;
        size_t                          pdu;
 
+       /*
+        * Flow API isolated mode overrides promisc and allmulti settings;
+        * they won't be applied if isolated mode is active
+        */
+       boolean_t                       isolated;
        boolean_t                       promisc;
        boolean_t                       allmulti;
 
index 0faf590..6b06f08 100644 (file)
@@ -361,8 +361,13 @@ sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode,
        if (*toggle != enabled) {
                *toggle = enabled;
 
-               if ((sa->state == SFC_ADAPTER_STARTED) &&
-                   (sfc_set_rx_mode(sa) != 0)) {
+               if (port->isolated) {
+                       sfc_warn(sa, "isolated mode is active on the port");
+                       sfc_warn(sa, "the change is to be applied on the next "
+                                    "start provided that isolated mode is "
+                                    "disabled prior the next start");
+               } else 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);
@@ -826,10 +831,17 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
        struct sfc_adapter *sa = dev->data->dev_private;
        const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
+       struct sfc_port *port = &sa->port;
        int rc;
 
        sfc_adapter_lock(sa);
 
+       if (port->isolated) {
+               sfc_err(sa, "isolated mode is active on the port");
+               sfc_err(sa, "will not set MAC address");
+               goto unlock;
+       }
+
        if (sa->state != SFC_ADAPTER_STARTED) {
                sfc_info(sa, "the port is not started");
                sfc_info(sa, "the new MAC address will be set on port start");
@@ -884,6 +896,12 @@ sfc_set_mc_addr_list(struct rte_eth_dev *dev, struct ether_addr *mc_addr_set,
        int rc;
        unsigned int i;
 
+       if (port->isolated) {
+               sfc_err(sa, "isolated mode is active on the port");
+               sfc_err(sa, "will not set multicast address list");
+               return -ENOTSUP;
+       }
+
        if (mc_addrs == NULL)
                return -ENOBUFS;
 
@@ -1091,8 +1109,9 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
                          struct rte_eth_rss_conf *rss_conf)
 {
        struct sfc_adapter *sa = dev->data->dev_private;
+       struct sfc_port *port = &sa->port;
 
-       if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE)
+       if ((sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) || port->isolated)
                return -ENOTSUP;
 
        if (sa->rss_channels == 0)
@@ -1121,9 +1140,13 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev,
                        struct rte_eth_rss_conf *rss_conf)
 {
        struct sfc_adapter *sa = dev->data->dev_private;
+       struct sfc_port *port = &sa->port;
        unsigned int efx_hash_types;
        int rc = 0;
 
+       if (port->isolated)
+               return -ENOTSUP;
+
        if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) {
                sfc_err(sa, "RSS is not available");
                return -ENOTSUP;
@@ -1188,9 +1211,10 @@ sfc_dev_rss_reta_query(struct rte_eth_dev *dev,
                       uint16_t reta_size)
 {
        struct sfc_adapter *sa = dev->data->dev_private;
+       struct sfc_port *port = &sa->port;
        int entry;
 
-       if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE)
+       if ((sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) || port->isolated)
                return -ENOTSUP;
 
        if (sa->rss_channels == 0)
@@ -1220,11 +1244,15 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev,
                        uint16_t reta_size)
 {
        struct sfc_adapter *sa = dev->data->dev_private;
+       struct sfc_port *port = &sa->port;
        unsigned int *rss_tbl_new;
        uint16_t entry;
        int rc;
 
 
+       if (port->isolated)
+               return -ENOTSUP;
+
        if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) {
                sfc_err(sa, "RSS is not available");
                return -ENOTSUP;
index c3ea43a..110dfb8 100644 (file)
@@ -1112,12 +1112,35 @@ sfc_flow_flush(struct rte_eth_dev *dev,
        return -ret;
 }
 
+static int
+sfc_flow_isolate(struct rte_eth_dev *dev, int enable,
+                struct rte_flow_error *error)
+{
+       struct sfc_adapter *sa = dev->data->dev_private;
+       struct sfc_port *port = &sa->port;
+       int ret = 0;
+
+       sfc_adapter_lock(sa);
+       if (sa->state != SFC_ADAPTER_INITIALIZED) {
+               rte_flow_error_set(error, EBUSY,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                  NULL, "please close the port first");
+               ret = -rte_errno;
+       } else {
+               port->isolated = (enable) ? B_TRUE : B_FALSE;
+       }
+       sfc_adapter_unlock(sa);
+
+       return ret;
+}
+
 const struct rte_flow_ops sfc_flow_ops = {
        .validate = sfc_flow_validate,
        .create = sfc_flow_create,
        .destroy = sfc_flow_destroy,
        .flush = sfc_flow_flush,
        .query = NULL,
+       .isolate = sfc_flow_isolate,
 };
 
 void
index ee96bcd..e7eea9f 100644 (file)
@@ -186,26 +186,29 @@ sfc_port_start(struct sfc_adapter *sa)
        if (rc != 0)
                goto fail_mac_pdu_set;
 
-       sfc_log_init(sa, "set MAC address");
-       rc = efx_mac_addr_set(sa->nic,
-                             sa->eth_dev->data->mac_addrs[0].addr_bytes);
-       if (rc != 0)
-               goto fail_mac_addr_set;
-
-       sfc_log_init(sa, "set MAC filters");
-       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;
+       if (!port->isolated) {
+               struct ether_addr *mac_addrs = sa->eth_dev->data->mac_addrs;
 
-       sfc_log_init(sa, "set multicast address list");
-       rc = efx_mac_multicast_list_set(sa->nic, port->mcast_addrs,
-                                       port->nb_mcast_addrs);
-       if (rc != 0)
-               goto fail_mcast_address_list_set;
+               sfc_log_init(sa, "set MAC address");
+               rc = efx_mac_addr_set(sa->nic, mac_addrs[0].addr_bytes);
+               if (rc != 0)
+                       goto fail_mac_addr_set;
+
+               sfc_log_init(sa, "set MAC filters");
+               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;
+
+               sfc_log_init(sa, "set multicast address list");
+               rc = efx_mac_multicast_list_set(sa->nic, port->mcast_addrs,
+                                               port->nb_mcast_addrs);
+               if (rc != 0)
+                       goto fail_mcast_address_list_set;
+       }
 
        if (port->mac_stats_reset_pending) {
                rc = sfc_port_reset_mac_stats(sa);
index e19ef6d..1bf8644 100644 (file)
@@ -630,6 +630,7 @@ retry:
 int
 sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 {
+       struct sfc_port *port = &sa->port;
        struct sfc_rxq_info *rxq_info;
        struct sfc_rxq *rxq;
        struct sfc_evq *evq;
@@ -664,7 +665,7 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 
        rxq->state |= SFC_RXQ_STARTED;
 
-       if (sw_index == 0) {
+       if ((sw_index == 0) && !port->isolated) {
                rc = sfc_rx_default_rxq_set_filter(sa, rxq);
                if (rc != 0)
                        goto fail_mac_filter_default_rxq_set;