net/mlx4_en: Add support for setting rxvlan offload OFF/ON
authorSaeed Mahameed <saeedm@mellanox.com>
Mon, 27 Oct 2014 09:37:42 +0000 (11:37 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 28 Oct 2014 21:18:01 +0000 (17:18 -0400)
Rename mlx4_en_timestamp_config to mlx4_en_reset_config and extend it to support
choosing RX vlan offload configuration.

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
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h

index 57dda95b67d8d4325e19f03b6d01f982cfc54cb7..285fccf01404123ea58d1c2ed73f4ad673a959ea 100644 (file)
 
 #include "mlx4_en.h"
 
-int mlx4_en_timestamp_config(struct net_device *dev, int tx_type, int rx_filter)
+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 == tx_type &&
-           priv->hwtstamp_config.rx_filter == rx_filter)
-               return 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) {
@@ -54,15 +64,36 @@ int mlx4_en_timestamp_config(struct net_device *dev, int tx_type, int rx_filter)
 
        mlx4_en_free_resources(priv);
 
-       en_warn(priv, "Changing Time Stamp configuration\n");
-
-       priv->hwtstamp_config.tx_type = tx_type;
-       priv->hwtstamp_config.rx_filter = rx_filter;
+       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;
+       }
 
-       if (rx_filter != HWTSTAMP_FILTER_NONE)
+       /* 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;
-       else
-               dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+       }
 
        err = mlx4_en_alloc_resources(priv);
        if (err) {
index f3032fec8fce03767580bd555a4760e8d7faba1e..c4bd2c7a8d2e997ad85108b9ef9082a5c8f33962 100644 (file)
@@ -2157,7 +2157,7 @@ static int mlx4_en_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
                return -ERANGE;
        }
 
-       if (mlx4_en_timestamp_config(dev, config.tx_type, config.rx_filter)) {
+       if (mlx4_en_reset_config(dev, config, dev->features)) {
                config.tx_type = HWTSTAMP_TX_OFF;
                config.rx_filter = HWTSTAMP_FILTER_NONE;
        }
index 946754ed393fd1c091939848e90900d5700f496b..6beb4d34dce02ce0fcd13e6d5f4fe292664fccb2 100644 (file)
@@ -835,6 +835,13 @@ void mlx4_en_cleanup_filters(struct mlx4_en_priv *priv);
 void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf);
 void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev);
 
+#define DEV_FEATURE_CHANGED(dev, new_features, feature) \
+       ((dev->features & feature) ^ (new_features & feature))
+
+int mlx4_en_reset_config(struct net_device *dev,
+                        struct hwtstamp_config ts_config,
+                        netdev_features_t new_features);
+
 /*
  * Functions for time stamping
  */
@@ -844,9 +851,6 @@ void mlx4_en_fill_hwtstamps(struct mlx4_en_dev *mdev,
                            u64 timestamp);
 void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev);
 void mlx4_en_remove_timestamp(struct mlx4_en_dev *mdev);
-int mlx4_en_timestamp_config(struct net_device *dev,
-                            int tx_type,
-                            int rx_filter);
 
 /* Globals
  */