net/mlx4_en: Add ethtool support for [rx|tx]vlan offload set to OFF/ON
authorSaeed Mahameed <saeedm@mellanox.com>
Mon, 27 Oct 2014 09:37:43 +0000 (11:37 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 28 Oct 2014 21:18:01 +0000 (17:18 -0400)
Move mlx4_en_reset_config to en_netdev.c as it now serves more general purpose.
Add support for turning OFF/ON the rx/tx vlan offlad.

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx4/en_clock.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c

index 285fccf..9990144 100644 (file)
 
 #include "mlx4_en.h"
 
-int mlx4_en_reset_config(struct net_device *dev,
-                        struct hwtstamp_config ts_config,
-                        netdev_features_t features)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_dev *mdev = priv->mdev;
-       int port_up = 0;
-       int err = 0;
-
-       if (priv->hwtstamp_config.tx_type == ts_config.tx_type &&
-           priv->hwtstamp_config.rx_filter == ts_config.rx_filter &&
-           !DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX))
-               return 0; /* Nothing to change */
-
-       if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX) &&
-           (features & NETIF_F_HW_VLAN_CTAG_RX) &&
-           (priv->hwtstamp_config.rx_filter != HWTSTAMP_FILTER_NONE)) {
-               en_warn(priv, "Can't turn ON rx vlan offload while time-stamping rx filter is ON\n");
-               return -EINVAL;
-       }
-
-       mutex_lock(&mdev->state_lock);
-       if (priv->port_up) {
-               port_up = 1;
-               mlx4_en_stop_port(dev, 1);
-       }
-
-       mlx4_en_free_resources(priv);
-
-       en_warn(priv, "Changing device configuration rx filter(%x) rx vlan(%x)\n",
-               ts_config.rx_filter, !!(features & NETIF_F_HW_VLAN_CTAG_RX));
-
-       priv->hwtstamp_config.tx_type = ts_config.tx_type;
-       priv->hwtstamp_config.rx_filter = ts_config.rx_filter;
-
-       if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX)) {
-               if (features & NETIF_F_HW_VLAN_CTAG_RX)
-                       dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
-               else
-                       dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
-       } else if (ts_config.rx_filter == HWTSTAMP_FILTER_NONE) {
-               /* RX time-stamping is OFF, update the RX vlan offload
-                * to the latest wanted state
-                */
-               if (dev->wanted_features & NETIF_F_HW_VLAN_CTAG_RX)
-                       dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
-               else
-                       dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
-       }
-
-       /* RX vlan offload and RX time-stamping can't co-exist !
-        * Regardless of the caller's choice,
-        * Turn Off RX vlan offload in case of time-stamping is ON
-        */
-       if (ts_config.rx_filter != HWTSTAMP_FILTER_NONE) {
-               if (dev->features & NETIF_F_HW_VLAN_CTAG_RX)
-                       en_warn(priv, "Turning off RX vlan offload since RX time-stamping is ON\n");
-               dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
-       }
-
-       err = mlx4_en_alloc_resources(priv);
-       if (err) {
-               en_err(priv, "Failed reallocating port resources\n");
-               goto out;
-       }
-       if (port_up) {
-               err = mlx4_en_start_port(dev);
-               if (err)
-                       en_err(priv, "Failed starting port\n");
-       }
-
-out:
-       mutex_unlock(&mdev->state_lock);
-       netdev_features_change(dev);
-       return err;
-}
-
 /* mlx4_en_read_clock - read raw cycle counter (to be used by time counter)
  */
 static cycle_t mlx4_en_read_clock(const struct cyclecounter *tc)
index c4bd2c7..3c6a58a 100644 (file)
@@ -2190,6 +2190,16 @@ static int mlx4_en_set_features(struct net_device *netdev,
                netdev_features_t features)
 {
        struct mlx4_en_priv *priv = netdev_priv(netdev);
+       int ret = 0;
+
+       if (DEV_FEATURE_CHANGED(netdev, features, NETIF_F_HW_VLAN_CTAG_RX)) {
+               en_info(priv, "Turn %s RX vlan strip offload\n",
+                       (features & NETIF_F_HW_VLAN_CTAG_RX) ? "ON" : "OFF");
+               ret = mlx4_en_reset_config(netdev, priv->hwtstamp_config,
+                                          features);
+               if (ret)
+                       return ret;
+       }
 
        if (features & NETIF_F_LOOPBACK)
                priv->ctrl_flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK);
@@ -2559,7 +2569,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        dev->features = dev->hw_features | NETIF_F_HIGHDMA |
                        NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
                        NETIF_F_HW_VLAN_CTAG_FILTER;
-       dev->hw_features |= NETIF_F_LOOPBACK;
+       dev->hw_features |= NETIF_F_LOOPBACK |
+                       NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
 
        if (mdev->dev->caps.steering_mode ==
            MLX4_STEERING_MODE_DEVICE_MANAGED)
@@ -2633,3 +2644,79 @@ out:
        return err;
 }
 
+int mlx4_en_reset_config(struct net_device *dev,
+                        struct hwtstamp_config ts_config,
+                        netdev_features_t features)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int port_up = 0;
+       int err = 0;
+
+       if (priv->hwtstamp_config.tx_type == ts_config.tx_type &&
+           priv->hwtstamp_config.rx_filter == ts_config.rx_filter &&
+           !DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX))
+               return 0; /* Nothing to change */
+
+       if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX) &&
+           (features & NETIF_F_HW_VLAN_CTAG_RX) &&
+           (priv->hwtstamp_config.rx_filter != HWTSTAMP_FILTER_NONE)) {
+               en_warn(priv, "Can't turn ON rx vlan offload while time-stamping rx filter is ON\n");
+               return -EINVAL;
+       }
+
+       mutex_lock(&mdev->state_lock);
+       if (priv->port_up) {
+               port_up = 1;
+               mlx4_en_stop_port(dev, 1);
+       }
+
+       mlx4_en_free_resources(priv);
+
+       en_warn(priv, "Changing device configuration rx filter(%x) rx vlan(%x)\n",
+               ts_config.rx_filter, !!(features & NETIF_F_HW_VLAN_CTAG_RX));
+
+       priv->hwtstamp_config.tx_type = ts_config.tx_type;
+       priv->hwtstamp_config.rx_filter = ts_config.rx_filter;
+
+       if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX)) {
+               if (features & NETIF_F_HW_VLAN_CTAG_RX)
+                       dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+               else
+                       dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
+       } else if (ts_config.rx_filter == HWTSTAMP_FILTER_NONE) {
+               /* RX time-stamping is OFF, update the RX vlan offload
+                * to the latest wanted state
+                */
+               if (dev->wanted_features & NETIF_F_HW_VLAN_CTAG_RX)
+                       dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+               else
+                       dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
+       }
+
+       /* RX vlan offload and RX time-stamping can't co-exist !
+        * Regardless of the caller's choice,
+        * Turn Off RX vlan offload in case of time-stamping is ON
+        */
+       if (ts_config.rx_filter != HWTSTAMP_FILTER_NONE) {
+               if (dev->features & NETIF_F_HW_VLAN_CTAG_RX)
+                       en_warn(priv, "Turning off RX vlan offload since RX time-stamping is ON\n");
+               dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
+       }
+
+       err = mlx4_en_alloc_resources(priv);
+       if (err) {
+               en_err(priv, "Failed reallocating port resources\n");
+               goto out;
+       }
+       if (port_up) {
+               err = mlx4_en_start_port(dev);
+               if (err)
+                       en_err(priv, "Failed starting port\n");
+       }
+
+out:
+       mutex_unlock(&mdev->state_lock);
+       netdev_features_change(dev);
+       return err;
+}