]> git.openfabrics.org - compat-rdma/compat-rdma.git/commitdiff
mlx4: Added SLES12 SP1 support
authorVladimir Sokolovsky <vlad@mellanox.com>
Thu, 1 Dec 2016 14:39:53 +0000 (16:39 +0200)
committerVladimir Sokolovsky <vlad@mellanox.com>
Thu, 1 Dec 2016 14:39:53 +0000 (16:39 +0200)
Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.com>
patches/0002-BACKPORT-mlx4.patch

index ce04fe4dc387696d9102d168a0790df0a15e08c8..ede88b51fe3a6642403d31c844809c3ab603fe6e 100644 (file)
@@ -3,20 +3,24 @@ Subject: [PATCH] BACKPORT: mlx4
 
 Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.com>
 ---
- drivers/infiniband/hw/mlx4/main.c               |  15 +
+ drivers/infiniband/hw/mlx4/main.c               |  19 +
+ drivers/net/ethernet/mellanox/mlx4/cmd.c        |   6 +
+ drivers/net/ethernet/mellanox/mlx4/en_clock.c   |  31 ++
  drivers/net/ethernet/mellanox/mlx4/en_cq.c      |   5 +
- drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c  |  19 ++
- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 365 +++++++++++++++++++++++-
+ drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c  |  19 +
+ drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 488 +++++++++++++++++++++++-
  drivers/net/ethernet/mellanox/mlx4/en_main.c    |   4 +
- drivers/net/ethernet/mellanox/mlx4/en_netdev.c  | 169 +++++++++++
- drivers/net/ethernet/mellanox/mlx4/en_rx.c      |  43 +++
- drivers/net/ethernet/mellanox/mlx4/en_tx.c      |  46 +++
+ drivers/net/ethernet/mellanox/mlx4/en_netdev.c  | 222 +++++++++++
+ drivers/net/ethernet/mellanox/mlx4/en_rx.c      |  58 +++
+ drivers/net/ethernet/mellanox/mlx4/en_tx.c      |  50 +++
  drivers/net/ethernet/mellanox/mlx4/intf.c       |   4 +
  drivers/net/ethernet/mellanox/mlx4/main.c       |  47 +++
  drivers/net/ethernet/mellanox/mlx4/mlx4.h       |   4 +
  drivers/net/ethernet/mellanox/mlx4/mlx4_en.h    |  30 ++
  drivers/net/ethernet/mellanox/mlx4/pd.c         |   4 +
- 13 files changed, 751 insertions(+), 4 deletions(-)
+ include/linux/mlx4/cmd.h                        |   2 +
+ include/linux/mlx4/device.h                     |   4 +
+ 17 files changed, 994 insertions(+), 3 deletions(-)
 
 diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
 index xxxxxxx..xxxxxxx xxxxxx
@@ -50,7 +54,25 @@ index xxxxxxx..xxxxxxx xxxxxx
  #define DRV_RELDATE   "Feb 2014"
  
  #define MLX4_IB_FLOW_MAX_PRIO 0xFFF
-@@ -2784,9 +2795,11 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
+@@ -131,6 +142,7 @@ static struct net_device *mlx4_ib_get_netdev(struct ib_device *device, u8 port_n
+       struct mlx4_ib_dev *ibdev = to_mdev(device);
+       struct net_device *dev;
++#ifdef HAVE_BONDING_H
+       rcu_read_lock();
+       dev = mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port_num);
+@@ -152,6 +164,9 @@ static struct net_device *mlx4_ib_get_netdev(struct ib_device *device, u8 port_n
+               dev_hold(dev);
+       rcu_read_unlock();
++#else
++      dev = mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port_num);
++#endif
+       return dev;
+ }
+@@ -2784,9 +2799,11 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
        }
  
        ibdev->ib_active = true;
@@ -62,7 +84,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  
        if (mlx4_is_mfunc(ibdev->dev))
                init_pkeys(ibdev);
-@@ -2914,10 +2927,12 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
+@@ -2914,10 +2931,12 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
  {
        struct mlx4_ib_dev *ibdev = ibdev_ptr;
        int p;
@@ -75,6 +97,149 @@ index xxxxxxx..xxxxxxx xxxxxx
        ibdev->ib_active = false;
        flush_workqueue(wq);
  
+diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
+index xxxxxxx..xxxxxxx xxxxxx
+--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
+@@ -3091,6 +3091,7 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)
+ }
+ EXPORT_SYMBOL_GPL(mlx4_set_vf_spoofchk);
++#ifdef HAVE_NDO_SET_VF_MAC
+ int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf)
+ {
+       struct mlx4_priv *priv = mlx4_priv(dev);
+@@ -3118,18 +3119,21 @@ int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_in
+       ivf->vlan               = s_info->default_vlan;
+       ivf->qos                = s_info->default_qos;
++#ifdef HAVE_TX_RATE_LIMIT
+       if (mlx4_is_vf_vst_and_prio_qos(dev, port, s_info))
+               ivf->max_tx_rate = s_info->tx_rate;
+       else
+               ivf->max_tx_rate = 0;
+       ivf->min_tx_rate        = 0;
++#endif
+       ivf->spoofchk           = s_info->spoofchk;
+       ivf->linkstate          = s_info->link_state;
+       return 0;
+ }
+ EXPORT_SYMBOL_GPL(mlx4_get_vf_config);
++#endif
+ int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state)
+ {
+@@ -3235,6 +3239,7 @@ if_stat_out:
+ }
+ EXPORT_SYMBOL_GPL(mlx4_get_counter_stats);
++#ifdef HAVE_NDO_GET_VF_STATS
+ int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
+                     struct ifla_vf_stats *vf_stats)
+ {
+@@ -3264,6 +3269,7 @@ int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
+       return err;
+ }
+ EXPORT_SYMBOL_GPL(mlx4_get_vf_stats);
++#endif
+ int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port)
+ {
+diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+index xxxxxxx..xxxxxxx xxxxxx
+--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+@@ -164,8 +164,12 @@ static int mlx4_en_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
+  * Read the timecounter and return the correct value in ns after converting
+  * it into a struct timespec.
+  **/
++#ifdef HAVE_PTP_CLOCK_INFO_GETTIME_32BIT
++static int mlx4_en_phc_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
++#else
+ static int mlx4_en_phc_gettime(struct ptp_clock_info *ptp,
+                              struct timespec64 *ts)
++#endif
+ {
+       struct mlx4_en_dev *mdev = container_of(ptp, struct mlx4_en_dev,
+                                               ptp_clock_info);
+@@ -176,7 +180,11 @@ static int mlx4_en_phc_gettime(struct ptp_clock_info *ptp,
+       ns = timecounter_read(&mdev->clock);
+       write_unlock_irqrestore(&mdev->clock_lock, flags);
++#ifdef HAVE_PTP_CLOCK_INFO_GETTIME_32BIT
++      *ts = ns_to_timespec(ns);
++#else
+       *ts = ns_to_timespec64(ns);
++#endif
+       return 0;
+ }
+@@ -190,11 +198,19 @@ static int mlx4_en_phc_gettime(struct ptp_clock_info *ptp,
+  * wall timer value.
+  **/
+ static int mlx4_en_phc_settime(struct ptp_clock_info *ptp,
++#ifdef HAVE_PTP_CLOCK_INFO_GETTIME_32BIT
++                             const struct timespec *ts)
++#else
+                              const struct timespec64 *ts)
++#endif
+ {
+       struct mlx4_en_dev *mdev = container_of(ptp, struct mlx4_en_dev,
+                                               ptp_clock_info);
++#ifdef HAVE_PTP_CLOCK_INFO_GETTIME_32BIT
++      u64 ns = timespec_to_ns(ts);
++#else
+       u64 ns = timespec64_to_ns(ts);
++#endif
+       unsigned long flags;
+       /* reset the timecounter */
+@@ -227,12 +243,19 @@ static const struct ptp_clock_info mlx4_en_ptp_clock_info = {
+       .n_alarm        = 0,
+       .n_ext_ts       = 0,
+       .n_per_out      = 0,
++#ifdef HAVE_PTP_CLOCK_INFO_N_PINS
+       .n_pins         = 0,
++#endif
+       .pps            = 0,
+       .adjfreq        = mlx4_en_phc_adjfreq,
+       .adjtime        = mlx4_en_phc_adjtime,
++#ifdef HAVE_PTP_CLOCK_INFO_GETTIME_32BIT
++      .gettime        = mlx4_en_phc_gettime,
++      .settime        = mlx4_en_phc_settime,
++#else
+       .gettime64      = mlx4_en_phc_gettime,
+       .settime64      = mlx4_en_phc_settime,
++#endif
+       .enable         = mlx4_en_phc_enable,
+ };
+@@ -258,7 +281,11 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
+ {
+       struct mlx4_dev *dev = mdev->dev;
+       unsigned long flags;
++#ifdef HAVE_CYCLECOUNTER_CYC2NS_4_PARAMS
+       u64 ns, zero = 0;
++#else
++      u64 ns;
++#endif
+       /* mlx4_en_init_timestamp is called for each netdev.
+        * mdev->ptp_clock is common for all ports, skip initialization if
+@@ -285,7 +312,11 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
+       /* Calculate period in seconds to call the overflow watchdog - to make
+        * sure counter is checked at least once every wrap around.
+        */
++#ifdef HAVE_CYCLECOUNTER_CYC2NS_4_PARAMS
+       ns = cyclecounter_cyc2ns(&mdev->cycles, mdev->cycles.mask, zero, &zero);
++#else
++      ns = cyclecounter_cyc2ns(&mdev->cycles, mdev->cycles.mask);
++#endif
+       do_div(ns, NSEC_PER_SEC / 2 / HZ);
+       mdev->overflow_period = ns;
 diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
 index xxxxxxx..xxxxxxx xxxxxx
 --- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c
@@ -491,7 +656,7 @@ index xxxxxxx..xxxxxxx xxxxxx
 +      cmd->supported = SUPPORTED_10000baseT_Full;
 +      cmd->advertising = ADVERTISED_10000baseT_Full;
 +      trans_type = priv->port_state.transceiver;
-+
 +      if (trans_type > 0 && trans_type <= 0xC) {
 +              cmd->port = PORT_FIBRE;
 +              cmd->transceiver = XCVR_EXTERNAL;
@@ -508,7 +673,7 @@ index xxxxxxx..xxxxxxx xxxxxx
 +      }
 +}
 +#endif
++
 +#ifdef HAVE_ETHTOOL_xLINKSETTINGS
  static int
  mlx4_en_get_link_ksettings(struct net_device *dev,
@@ -658,7 +823,12 @@ index xxxxxxx..xxxxxxx xxxxxx
        mutex_unlock(&mdev->state_lock);
        return err;
  }
-@@ -1112,7 +1396,11 @@ static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
+@@ -1108,18 +1392,27 @@ static void mlx4_en_get_ringparam(struct net_device *dev,
+       param->tx_pending = priv->tx_ring[0]->size;
+ }
++#if defined(HAVE_RXFH_INDIR_SIZE) || defined(HAVE_RXFH_INDIR_SIZE_EXT)
+ static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
  {
        struct mlx4_en_priv *priv = netdev_priv(dev);
  
@@ -668,17 +838,44 @@ index xxxxxxx..xxxxxxx xxxxxx
 +      return priv->rx_ring_num;
 +#endif
  }
++#endif
  
++#if defined(HAVE_GET_SET_RXFH) && !defined(HAVE_GET_SET_RXFH_INDIR_EXT)
  static u32 mlx4_en_get_rxfh_key_size(struct net_device *netdev)
-@@ -1146,6 +1434,7 @@ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key,
+ {
+       return MLX4_EN_RSS_KEY_SIZE;
+ }
++#endif
++#if defined(HAVE_GET_SET_RXFH) && !defined(HAVE_GET_SET_RXFH_INDIR_EXT) && defined(HAVE_ETH_SS_RSS_HASH_FUNCS)
+ static int mlx4_en_check_rxfh_func(struct net_device *dev, u8 hfunc)
+ {
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+@@ -1141,11 +1434,23 @@ static int mlx4_en_check_rxfh_func(struct net_device *dev, u8 hfunc)
+       return -EINVAL;
+ }
++#endif
++#if defined(HAVE_GET_SET_RXFH) && !defined(HAVE_GET_SET_RXFH_INDIR_EXT)
++#ifdef HAVE_ETH_SS_RSS_HASH_FUNCS
+ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key,
                            u8 *hfunc)
++#else
++static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key)
++#endif
++#elif defined(HAVE_GET_SET_RXFH_INDIR) || defined (HAVE_GET_SET_RXFH_INDIR_EXT)
++static int mlx4_en_get_rxfh_indir(struct net_device *dev, u32 *ring_index)
++#elif defined(CONFIG_SYSFS_INDIR_SETTING)
++int mlx4_en_get_rxfh_indir(struct net_device *dev, u32 *ring_index)
++#endif
  {
        struct mlx4_en_priv *priv = netdev_priv(dev);
 +#ifdef HAVE_ETHTOOL_xLINKSETTINGS
        u32 n = mlx4_en_get_rxfh_indir_size(dev);
        u32 i, rss_rings;
        int err = 0;
-@@ -1158,6 +1447,22 @@ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key,
+@@ -1158,18 +1463,50 @@ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key,
                        break;
                ring_index[i] = i % rss_rings;
        }
@@ -698,11 +895,29 @@ index xxxxxxx..xxxxxxx xxxxxx
 +                      rss_map->base_qpn;
 +      }
 +#endif
++#if defined(HAVE_GET_SET_RXFH) && !defined(HAVE_GET_SET_RXFH_INDIR_EXT)
        if (key)
                memcpy(key, priv->rss_key, MLX4_EN_RSS_KEY_SIZE);
++#ifdef HAVE_ETH_SS_RSS_HASH_FUNCS
        if (hfunc)
-@@ -1169,7 +1474,9 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
+               *hfunc = priv->rss_hash_fn;
++#endif
++#endif
+       return err;
+ }
++#if defined(HAVE_GET_SET_RXFH) && !defined(HAVE_GET_SET_RXFH_INDIR_EXT)
+ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
++#ifdef HAVE_ETH_SS_RSS_HASH_FUNCS
                            const u8 *key, const u8 hfunc)
++#else
++                          const u8 *key)
++#endif
++#elif defined(HAVE_GET_SET_RXFH_INDIR) || defined (HAVE_GET_SET_RXFH_INDIR_EXT)
++static int mlx4_en_set_rxfh_indir(struct net_device *dev, const u32 *ring_index)
++#elif defined(CONFIG_SYSFS_INDIR_SETTING)
++int mlx4_en_set_rxfh_indir(struct net_device *dev, const u32 *ring_index)
++#endif
  {
        struct mlx4_en_priv *priv = netdev_priv(dev);
 +#ifdef HAVE_ETHTOOL_xLINKSETTINGS
@@ -711,7 +926,7 @@ index xxxxxxx..xxxxxxx xxxxxx
        struct mlx4_en_dev *mdev = priv->mdev;
        int port_up = 0;
        int err = 0;
-@@ -1179,6 +1486,7 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
+@@ -1179,6 +1516,7 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
        /* Calculate RSS table size and make sure flows are spread evenly
         * between rings
         */
@@ -719,7 +934,7 @@ index xxxxxxx..xxxxxxx xxxxxx
        for (i = 0; i < n; i++) {
                if (!ring_index)
                        break;
-@@ -1191,6 +1499,20 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
+@@ -1191,16 +1529,32 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
  
        if (!rss_rings)
                rss_rings = n;
@@ -740,7 +955,106 @@ index xxxxxxx..xxxxxxx xxxxxx
  
        /* RSS table size must be an order of 2 */
        if (!is_power_of_2(rss_rings))
-@@ -1718,8 +2040,10 @@ static int mlx4_en_set_channels(struct net_device *dev,
+               return -EINVAL;
++#if defined(HAVE_GET_SET_RXFH) && !defined(HAVE_GET_SET_RXFH_INDIR_EXT) && defined(HAVE_ETH_SS_RSS_HASH_FUNCS)
+       if (hfunc != ETH_RSS_HASH_NO_CHANGE) {
+               err = mlx4_en_check_rxfh_func(dev, hfunc);
+               if (err)
+                       return err;
+       }
++#endif
+       mutex_lock(&mdev->state_lock);
+       if (priv->port_up) {
+@@ -1210,10 +1564,14 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index,
+       if (ring_index)
+               priv->prof->rss_rings = rss_rings;
++#if defined(HAVE_GET_SET_RXFH) && !defined(HAVE_GET_SET_RXFH_INDIR_EXT)
+       if (key)
+               memcpy(priv->rss_key, key, MLX4_EN_RSS_KEY_SIZE);
++#endif
++#if defined(HAVE_GET_SET_RXFH) && !defined(HAVE_GET_SET_RXFH_INDIR_EXT) && defined(HAVE_ETH_SS_RSS_HASH_FUNCS)
+       if (hfunc !=  ETH_RSS_HASH_NO_CHANGE)
+               priv->rss_hash_fn = hfunc;
++#endif
+       if (port_up) {
+               err = mlx4_en_start_port(dev);
+@@ -1238,11 +1596,13 @@ static int mlx4_en_validate_flow(struct net_device *dev,
+       if (cmd->fs.location >= MAX_NUM_OF_FS_RULES)
+               return -EINVAL;
++#ifdef HAVE_ETHTOOL_FLOW_EXT_H_DEST
+       if (cmd->fs.flow_type & FLOW_MAC_EXT) {
+               /* dest mac mask must be ff:ff:ff:ff:ff:ff */
+               if (!is_broadcast_ether_addr(cmd->fs.m_ext.h_dest))
+                       return -EINVAL;
+       }
++#endif
+       switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
+       case TCP_V4_FLOW:
+@@ -1334,9 +1694,11 @@ static int mlx4_en_ethtool_add_mac_rule_by_ipv4(struct mlx4_en_priv *priv,
+       unsigned char mac[ETH_ALEN];
+       if (!ipv4_is_multicast(ipv4_dst)) {
++#ifdef HAVE_ETHTOOL_FLOW_EXT_H_DEST
+               if (cmd->fs.flow_type & FLOW_MAC_EXT)
+                       memcpy(&mac, cmd->fs.h_ext.h_dest, ETH_ALEN);
+               else
++#endif
+                       memcpy(&mac, priv->dev->dev_addr, ETH_ALEN);
+       } else {
+               ip_eth_mc_map(ipv4_dst, mac);
+@@ -1632,8 +1994,13 @@ static int mlx4_en_get_num_flows(struct mlx4_en_priv *priv)
+ }
++#ifdef HAVE_ETHTOOL_OPS_GET_RXNFC_U32_RULE_LOCS
+ static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+                            u32 *rule_locs)
++#else
++static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
++                           void *rule_locs)
++#endif
+ {
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+@@ -1661,7 +2028,11 @@ static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+               while ((!err || err == -ENOENT) && priority < cmd->rule_cnt) {
+                       err = mlx4_en_get_flow(dev, cmd, i);
+                       if (!err)
++#ifdef HAVE_ETHTOOL_OPS_GET_RXNFC_U32_RULE_LOCS
+                               rule_locs[priority++] = i;
++#else
++                              ((u32 *)(rule_locs))[priority++] = i;
++#endif
+                       i++;
+               }
+               err = 0;
+@@ -1707,10 +2078,19 @@ static void mlx4_en_get_channels(struct net_device *dev,
+       memset(channel, 0, sizeof(*channel));
+       channel->max_rx = MAX_RX_RINGS;
++#ifdef HAVE_NEW_TX_RING_SCHEME
+       channel->max_tx = MLX4_EN_MAX_TX_RING_P_UP;
++#else
++      channel->max_tx = MLX4_EN_NUM_TX_RINGS * 2;
++#endif
+       channel->rx_count = priv->rx_ring_num;
++#ifdef HAVE_NEW_TX_RING_SCHEME
+       channel->tx_count = priv->tx_ring_num / MLX4_EN_NUM_UP;
++#else
++      channel->tx_count = priv->tx_ring_num -
++                          (!!priv->prof->rx_ppp) * MLX4_EN_NUM_PPP_RINGS;
++#endif
+ }
+ static int mlx4_en_set_channels(struct net_device *dev,
+@@ -1718,28 +2098,39 @@ static int mlx4_en_set_channels(struct net_device *dev,
  {
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
@@ -751,7 +1065,13 @@ index xxxxxxx..xxxxxxx xxxxxx
        int port_up = 0;
        int err = 0;
  
-@@ -1729,17 +2053,22 @@ static int mlx4_en_set_channels(struct net_device *dev,
+       if (channel->other_count || channel->combined_count ||
++#ifdef HAVE_NEW_TX_RING_SCHEME
+           channel->tx_count > MLX4_EN_MAX_TX_RING_P_UP ||
++#else
++          channel->tx_count > MLX4_EN_NUM_TX_RINGS * 2 ||
++#endif
+           channel->rx_count > MAX_RX_RINGS ||
            !channel->tx_count || !channel->rx_count)
                return -EINVAL;
  
@@ -774,7 +1094,7 @@ index xxxxxxx..xxxxxxx xxxxxx
        memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
        new_prof.num_tx_rings_p_up = channel->tx_count;
        new_prof.tx_ring_num = channel->tx_count * MLX4_EN_NUM_UP;
-@@ -1748,16 +2077,35 @@ static int mlx4_en_set_channels(struct net_device *dev,
+@@ -1748,20 +2139,50 @@ static int mlx4_en_set_channels(struct net_device *dev,
        err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof);
        if (err)
                goto out;
@@ -789,9 +1109,14 @@ index xxxxxxx..xxxxxxx xxxxxx
        mlx4_en_safe_replace_resources(priv, tmp);
 +#else
 +      mlx4_en_free_resources(priv);
-+
 +      priv->num_tx_rings_p_up = channel->tx_count;
++#ifdef HAVE_NEW_TX_RING_SCHEME
 +      priv->tx_ring_num = channel->tx_count * MLX4_EN_NUM_UP;
++#else
++      priv->tx_ring_num = channel->tx_count +
++                          (!!priv->prof->rx_ppp) * MLX4_EN_NUM_PPP_RINGS;
++#endif
 +      priv->rx_ring_num = channel->rx_count;
 +
 +      err = mlx4_en_alloc_resources(priv);
@@ -800,17 +1125,27 @@ index xxxxxxx..xxxxxxx xxxxxx
 +              goto out;
 +      }
 +#endif
++
 +#ifdef HAVE_FILTER_XDP
        netif_set_real_num_tx_queues(dev, priv->tx_ring_num -
                                                        priv->xdp_ring_num);
 +#else
++#ifdef HAVE_NEW_TX_RING_SCHEME
 +      netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
++#else
++      dev->real_num_tx_queues = priv->tx_ring_num;
++#endif
 +#endif
        netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
  
++#ifdef HAVE_NEW_TX_RING_SCHEME
        if (dev->num_tc)
-@@ -1774,7 +2122,9 @@ static int mlx4_en_set_channels(struct net_device *dev,
+               mlx4_en_setup_tc(dev, MLX4_EN_NUM_UP);
++#endif
+       en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num);
+       en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num);
+@@ -1774,11 +2195,14 @@ static int mlx4_en_set_channels(struct net_device *dev,
  
        err = mlx4_en_moderation_update(priv);
  out:
@@ -820,7 +1155,28 @@ index xxxxxxx..xxxxxxx xxxxxx
        mutex_unlock(&mdev->state_lock);
        return err;
  }
-@@ -1867,6 +2217,7 @@ static u32 mlx4_en_get_priv_flags(struct net_device *dev)
++#if defined(HAVE_GET_TS_INFO) || defined(HAVE_GET_TS_INFO_EXT)
+ static int mlx4_en_get_ts_info(struct net_device *dev,
+                              struct ethtool_ts_info *info)
+ {
+@@ -1804,12 +2228,15 @@ static int mlx4_en_get_ts_info(struct net_device *dev,
+                       (1 << HWTSTAMP_FILTER_NONE) |
+                       (1 << HWTSTAMP_FILTER_ALL);
++#if defined (HAVE_PTP_CLOCK_INFO) && (defined (CONFIG_PTP_1588_CLOCK) || defined(CONFIG_PTP_1588_CLOCK_MODULE))
+               if (mdev->ptp_clock)
+                       info->phc_index = ptp_clock_index(mdev->ptp_clock);
++#endif
+       }
+       return ret;
+ }
++#endif
+ static int mlx4_en_set_priv_flags(struct net_device *dev, u32 flags)
+ {
+@@ -1867,6 +2294,7 @@ static u32 mlx4_en_get_priv_flags(struct net_device *dev)
        return priv->pflags;
  }
  
@@ -828,15 +1184,41 @@ index xxxxxxx..xxxxxxx xxxxxx
  static int mlx4_en_get_tunable(struct net_device *dev,
                               const struct ethtool_tunable *tuna,
                               void *data)
-@@ -1908,6 +2259,7 @@ static int mlx4_en_set_tunable(struct net_device *dev,
+@@ -1908,7 +2336,9 @@ static int mlx4_en_set_tunable(struct net_device *dev,
  
        return ret;
  }
 +#endif
  
++#if defined(HAVE_GET_MODULE_EEPROM) || defined(HAVE_GET_MODULE_EEPROM_EXT)
  static int mlx4_en_get_module_info(struct net_device *dev,
                                   struct ethtool_modinfo *modinfo)
-@@ -2018,8 +2370,13 @@ static int mlx4_en_set_phys_id(struct net_device *dev,
+ {
+@@ -1951,7 +2381,9 @@ static int mlx4_en_get_module_info(struct net_device *dev,
+       return 0;
+ }
++#endif
++#if defined(HAVE_GET_MODULE_EEPROM) || defined(HAVE_GET_MODULE_EEPROM_EXT)
+ static int mlx4_en_get_module_eeprom(struct net_device *dev,
+                                    struct ethtool_eeprom *ee,
+                                    u8 *data)
+@@ -1989,7 +2421,9 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev,
+       }
+       return 0;
+ }
++#endif
++#if defined(HAVE_SET_PHYS_ID) || defined(HAVE_SET_PHYS_ID_EXT)
+ static int mlx4_en_set_phys_id(struct net_device *dev,
+                              enum ethtool_phys_id_state state)
+ {
+@@ -2015,17 +2449,25 @@ static int mlx4_en_set_phys_id(struct net_device *dev,
+       err = mlx4_SET_PORT_BEACON(mdev->dev, priv->port, beacon_duration);
+       return err;
+ }
++#endif
  
  const struct ethtool_ops mlx4_en_ethtool_ops = {
        .get_drvinfo = mlx4_en_get_drvinfo,
@@ -850,22 +1232,78 @@ index xxxxxxx..xxxxxxx xxxxxx
        .get_link = ethtool_op_get_link,
        .get_strings = mlx4_en_get_strings,
        .get_sset_count = mlx4_en_get_sset_count,
-@@ -2047,13 +2404,13 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
+       .get_ethtool_stats = mlx4_en_get_ethtool_stats,
+       .self_test = mlx4_en_self_test,
++#if defined(HAVE_SET_PHYS_ID) && !defined(HAVE_SET_PHYS_ID_EXT)
+       .set_phys_id = mlx4_en_set_phys_id,
++#endif
+       .get_wol = mlx4_en_get_wol,
+       .set_wol = mlx4_en_set_wol,
+       .get_msglevel = mlx4_en_get_msglevel,
+@@ -2038,22 +2480,62 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
+       .set_ringparam = mlx4_en_set_ringparam,
+       .get_rxnfc = mlx4_en_get_rxnfc,
+       .set_rxnfc = mlx4_en_set_rxnfc,
++#if defined(HAVE_RXFH_INDIR_SIZE) && !defined(HAVE_RXFH_INDIR_SIZE_EXT)
+       .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size,
++#endif
++#if defined(HAVE_GET_SET_RXFH) && !defined(HAVE_GET_SET_RXFH_INDIR_EXT)
+       .get_rxfh_key_size = mlx4_en_get_rxfh_key_size,
+       .get_rxfh = mlx4_en_get_rxfh,
+       .set_rxfh = mlx4_en_set_rxfh,
++#elif defined(HAVE_GET_SET_RXFH_INDIR) && !defined(HAVE_GET_SET_RXFH_INDIR_EXT)
++      .get_rxfh_indir = mlx4_en_get_rxfh_indir,
++      .set_rxfh_indir = mlx4_en_set_rxfh_indir,
++#endif
++#ifdef HAVE_GET_SET_CHANNELS
+       .get_channels = mlx4_en_get_channels,
+       .set_channels = mlx4_en_set_channels,
++#endif
++#if defined(HAVE_GET_TS_INFO) && !defined(HAVE_GET_TS_INFO_EXT)
        .get_ts_info = mlx4_en_get_ts_info,
++#endif
        .set_priv_flags = mlx4_en_set_priv_flags,
        .get_priv_flags = mlx4_en_get_priv_flags,
 +#ifdef HAVE_GET_SET_TUNABLE
        .get_tunable            = mlx4_en_get_tunable,
        .set_tunable            = mlx4_en_set_tunable,
 +#endif
++#ifdef HAVE_GET_MODULE_EEPROM
        .get_module_info = mlx4_en_get_module_info,
        .get_module_eeprom = mlx4_en_get_module_eeprom
++#endif
  };
  
+-
++#ifdef HAVE_ETHTOOL_OPS_EXT
++const struct ethtool_ops_ext mlx4_en_ethtool_ops_ext = {
++      .size = sizeof(struct ethtool_ops_ext),
++#ifdef HAVE_RXFH_INDIR_SIZE_EXT
++      .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size,
++#endif
++#ifdef HAVE_GET_SET_RXFH_INDIR_EXT
++      .get_rxfh_indir = mlx4_en_get_rxfh_indir,
++      .set_rxfh_indir = mlx4_en_set_rxfh_indir,
++#endif
++#ifdef HAVE_GET_SET_CHANNELS_EXT
++      .get_channels = mlx4_en_get_channels,
++      .set_channels = mlx4_en_set_channels,
++#endif
++#ifdef HAVE_GET_TS_INFO_EXT
++      .get_ts_info = mlx4_en_get_ts_info,
++#endif
++#ifdef HAVE_SET_PHYS_ID_EXT
++      .set_phys_id = mlx4_en_set_phys_id,
++#endif
++#ifdef HAVE_GET_MODULE_EEPROM_EXT
++      .get_module_info = mlx4_en_get_module_info,
++      .get_module_eeprom = mlx4_en_get_module_eeprom,
++#endif
++};
++#endif
  
  
--
--
 diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
 index xxxxxxx..xxxxxxx xxxxxx
 --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -973,21 +1411,27 @@ index xxxxxxx..xxxxxxx xxxxxx
  
                /* Arm CQ for TX completions */
                mlx4_en_arm_cq(priv, cq);
-@@ -1729,8 +1742,13 @@ int mlx4_en_start_port(struct net_device *dev)
+@@ -1729,8 +1742,19 @@ int mlx4_en_start_port(struct net_device *dev)
        /* Schedule multicast task to populate multicast list */
        queue_work(mdev->workqueue, &priv->rx_mode_task);
  
 +#ifdef HAVE_UDP_TUNNEL_GET_RX_INFO
++#if (defined(HAVE_VXLAN_DYNAMIC_PORT) || defined(HAVE_UDP_TUNNEL_GET_RX_INFO))
        if (priv->mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN)
                udp_tunnel_get_rx_info(dev);
-+#elif CONFIG_MLX4_EN_VXLAN
++#elif defined(CONFIG_MLX4_EN_VXLAN)
 +      if (priv->mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN)
++      #ifdef HAVE_VXLAN_DYNAMIC_PORT
 +              vxlan_get_rx_port(dev);
++      #elif defined(HAVE_UDP_TUNNEL_GET_RX_INFO)
++              udp_tunnel_get_rx_info(dev);
++      #endif
++#endif
 +#endif
  
        priv->port_up = true;
        netif_tx_start_all_queues(dev);
-@@ -1986,7 +2004,11 @@ static int mlx4_en_close(struct net_device *dev)
+@@ -1986,7 +2010,11 @@ static int mlx4_en_close(struct net_device *dev)
        return 0;
  }
  
@@ -999,7 +1443,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  {
        int i;
  
-@@ -2011,7 +2033,11 @@ static void mlx4_en_free_resources(struct mlx4_en_priv *priv)
+@@ -2011,7 +2039,11 @@ static void mlx4_en_free_resources(struct mlx4_en_priv *priv)
  
  }
  
@@ -1011,7 +1455,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  {
        struct mlx4_en_port_profile *prof = priv->prof;
        int i;
-@@ -2158,8 +2184,10 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
+@@ -2158,8 +2190,10 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
  
        /* Unregister device - this will close the port if it was up */
        if (priv->registered) {
@@ -1022,7 +1466,7 @@ index xxxxxxx..xxxxxxx xxxxxx
                if (shutdown)
                        mlx4_en_shutdown(dev);
                else
-@@ -2209,11 +2237,13 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
+@@ -2209,11 +2243,13 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
                en_err(priv, "Bad MTU size:%d.\n", new_mtu);
                return -EPERM;
        }
@@ -1036,15 +1480,25 @@ index xxxxxxx..xxxxxxx xxxxxx
        dev->mtu = new_mtu;
  
        if (netif_running(dev)) {
-@@ -2418,6 +2448,7 @@ static int mlx4_en_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
+@@ -2408,6 +2444,7 @@ static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos)
+       return mlx4_set_vf_vlan(mdev->dev, en_priv->port, vf, vlan, qos);
+ }
++#ifdef HAVE_TX_RATE_LIMIT
+ static int mlx4_en_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
+                              int max_tx_rate)
+ {
+@@ -2417,7 +2454,9 @@ static int mlx4_en_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
+       return mlx4_set_vf_rate(mdev->dev, en_priv->port, vf, min_tx_rate,
                                max_tx_rate);
  }
++#endif
  
-+#ifdef HAVE_NETDEV_OPS_EXT_NDO_SET_VF_SPOOFCHK
++#if defined(HAVE_VF_INFO_SPOOFCHK) || defined(HAVE_NETDEV_OPS_EXT_NDO_SET_VF_SPOOFCHK)
  static int mlx4_en_set_vf_spoofchk(struct net_device *dev, int vf, bool setting)
  {
        struct mlx4_en_priv *en_priv = netdev_priv(dev);
-@@ -2425,7 +2456,9 @@ static int mlx4_en_set_vf_spoofchk(struct net_device *dev, int vf, bool setting)
+@@ -2425,7 +2464,9 @@ static int mlx4_en_set_vf_spoofchk(struct net_device *dev, int vf, bool setting)
  
        return mlx4_set_vf_spoofchk(mdev->dev, en_priv->port, vf, setting);
  }
@@ -1054,27 +1508,31 @@ index xxxxxxx..xxxxxxx xxxxxx
  static int mlx4_en_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivf)
  {
        struct mlx4_en_priv *en_priv = netdev_priv(dev);
-@@ -2433,7 +2466,9 @@ static int mlx4_en_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_
+@@ -2433,7 +2474,9 @@ static int mlx4_en_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_
  
        return mlx4_get_vf_config(mdev->dev, en_priv->port, vf, ivf);
  }
 +#endif
  
-+#ifdef HAVE_NETDEV_OPS_EXT_NDO_SET_VF_LINK_STATE
++#if defined(HAVE_NETDEV_OPS_NDO_SET_VF_LINK_STATE) || defined(HAVE_NETDEV_OPS_EXT_NDO_SET_VF_LINK_STATE)
  static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_state)
  {
        struct mlx4_en_priv *en_priv = netdev_priv(dev);
-@@ -2441,6 +2476,7 @@ static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_st
+@@ -2441,7 +2484,9 @@ static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_st
  
        return mlx4_set_vf_link_state(mdev->dev, en_priv->port, vf, link_state);
  }
 +#endif
  
++#ifdef HAVE_NDO_GET_VF_STATS
  static int mlx4_en_get_vf_stats(struct net_device *dev, int vf,
                                struct ifla_vf_stats *vf_stats)
-@@ -2451,9 +2487,14 @@ static int mlx4_en_get_vf_stats(struct net_device *dev, int vf,
+ {
+@@ -2450,10 +2495,16 @@ static int mlx4_en_get_vf_stats(struct net_device *dev, int vf,
        return mlx4_get_vf_stats(mdev->dev, en_priv->port, vf, vf_stats);
  }
++#endif
  
 +#if defined(HAVE_NETDEV_NDO_GET_PHYS_PORT_ID) || defined(HAVE_NETDEV_EXT_NDO_GET_PHYS_PORT_ID)
  #define PORT_ID_BYTE_LEN 8
@@ -1087,15 +1545,17 @@ index xxxxxxx..xxxxxxx xxxxxx
  {
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_dev *mdev = priv->mdev->dev;
-@@ -2470,6 +2511,7 @@ static int mlx4_en_get_phys_port_id(struct net_device *dev,
+@@ -2470,7 +2521,9 @@ static int mlx4_en_get_phys_port_id(struct net_device *dev,
        }
        return 0;
  }
 +#endif
  
++#if defined(HAVE_VXLAN_ENABLED) || defined(HAVE_UDP_TUNNEL_GET_RX_INFO)
  static void mlx4_en_add_vxlan_offloads(struct work_struct *work)
  {
-@@ -2490,12 +2532,20 @@ out:
+       int ret;
+@@ -2490,12 +2543,20 @@ out:
        }
  
        /* set offloads */
@@ -1116,7 +1576,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  }
  
  static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
-@@ -2504,12 +2554,20 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
+@@ -2504,12 +2565,20 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
        struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
                                                 vxlan_del_task);
        /* unset offloads */
@@ -1137,7 +1597,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  
        ret = mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port,
                                  VXLAN_STEER_BY_OUTER_MAC, 0);
-@@ -2519,6 +2577,7 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
+@@ -2519,6 +2588,7 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
        priv->vxlan_port = 0;
  }
  
@@ -1145,7 +1605,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  static void mlx4_en_add_vxlan_port(struct  net_device *dev,
                                   struct udp_tunnel_info *ti)
  {
-@@ -2570,6 +2629,51 @@ static void mlx4_en_del_vxlan_port(struct  net_device *dev,
+@@ -2570,7 +2640,53 @@ static void mlx4_en_del_vxlan_port(struct  net_device *dev,
  
        queue_work(priv->mdev->workqueue, &priv->vxlan_del_task);
  }
@@ -1195,27 +1655,32 @@ index xxxxxxx..xxxxxxx xxxxxx
 +}
 +#endif
  
++#ifdef HAVE_NETDEV_FEATURES_T
  static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
                                                struct net_device *dev,
-@@ -2595,6 +2699,7 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
+                                               netdev_features_t features)
+@@ -2594,7 +2710,9 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
        return features;
  }
++#endif
  
 +#ifdef HAVE_NDO_SET_TX_MAXRATE
  static int mlx4_en_set_tx_maxrate(struct net_device *dev, int queue_index, u32 maxrate)
  {
        struct mlx4_en_priv *priv = netdev_priv(dev);
-@@ -2621,7 +2726,9 @@ static int mlx4_en_set_tx_maxrate(struct net_device *dev, int queue_index, u32 m
+@@ -2621,7 +2739,10 @@ static int mlx4_en_set_tx_maxrate(struct net_device *dev, int queue_index, u32 m
                             &params);
        return err;
  }
 +#endif
++#endif
  
 +#ifdef HAVE_FILTER_XDP
  static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog)
  {
        struct mlx4_en_priv *priv = netdev_priv(dev);
-@@ -2718,6 +2825,7 @@ static int mlx4_xdp(struct net_device *dev, struct netdev_xdp *xdp)
+@@ -2718,6 +2839,7 @@ static int mlx4_xdp(struct net_device *dev, struct netdev_xdp *xdp)
                return -EINVAL;
        }
  }
@@ -1223,7 +1688,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  
  static const struct net_device_ops mlx4_netdev_ops = {
        .ndo_open               = mlx4_en_open,
-@@ -2738,16 +2846,33 @@ static const struct net_device_ops mlx4_netdev_ops = {
+@@ -2738,16 +2860,35 @@ static const struct net_device_ops mlx4_netdev_ops = {
  #endif
        .ndo_set_features       = mlx4_en_set_features,
        .ndo_fix_features       = mlx4_en_fix_features,
@@ -1247,7 +1712,9 @@ index xxxxxxx..xxxxxxx xxxxxx
 +      .ndo_add_vxlan_port     = mlx4_en_add_vxlan_port,
 +      .ndo_del_vxlan_port     = mlx4_en_del_vxlan_port,
 +#endif
++#ifdef HAVE_NETDEV_FEATURES_T
        .ndo_features_check     = mlx4_en_features_check,
++#endif
 +#ifdef HAVE_NDO_SET_TX_MAXRATE
        .ndo_set_tx_maxrate     = mlx4_en_set_tx_maxrate,
 +#endif
@@ -1257,17 +1724,22 @@ index xxxxxxx..xxxxxxx xxxxxx
  };
  
  static const struct net_device_ops mlx4_netdev_ops_master = {
-@@ -2766,25 +2891,46 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
+@@ -2765,27 +2906,79 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
+       .ndo_vlan_rx_kill_vid   = mlx4_en_vlan_rx_kill_vid,
        .ndo_set_vf_mac         = mlx4_en_set_vf_mac,
        .ndo_set_vf_vlan        = mlx4_en_set_vf_vlan,
++#ifdef HAVE_TX_RATE_LIMIT
        .ndo_set_vf_rate        = mlx4_en_set_vf_rate,
-+#ifdef HAVE_NETDEV_OPS_EXT_NDO_SET_VF_SPOOFCHK
++#endif
++#ifdef HAVE_VF_INFO_SPOOFCHK
        .ndo_set_vf_spoofchk    = mlx4_en_set_vf_spoofchk,
 +#endif
-+#ifdef HAVE_NETDEV_OPS_EXT_NDO_SET_VF_LINK_STATE
++#ifdef HAVE_NETDEV_OPS_NDO_SET_VF_LINK_STATE
        .ndo_set_vf_link_state  = mlx4_en_set_vf_link_state,
 +#endif
++#ifdef HAVE_NDO_GET_VF_STATS
        .ndo_get_vf_stats       = mlx4_en_get_vf_stats,
++#endif
 +#ifdef HAVE_NDO_SET_VF_MAC
        .ndo_get_vf_config      = mlx4_en_get_vf_config,
 +#endif
@@ -1284,7 +1756,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  #ifdef CONFIG_RFS_ACCEL
        .ndo_rx_flow_steer      = mlx4_en_filter_rfs,
  #endif
-+#ifdef HAVE_NETDEV_EXT_NDO_GET_PHYS_PORT_ID
++#ifdef HAVE_NETDEV_NDO_GET_PHYS_PORT_ID
        .ndo_get_phys_port_id   = mlx4_en_get_phys_port_id,
 +#endif
 +#ifdef HAVE_NDO_UDP_TUNNEL_ADD
@@ -1294,17 +1766,45 @@ index xxxxxxx..xxxxxxx xxxxxx
 +      .ndo_add_vxlan_port     = mlx4_en_add_vxlan_port,
 +      .ndo_del_vxlan_port     = mlx4_en_del_vxlan_port,
 +#endif
++#ifdef HAVE_NETDEV_FEATURES_T
        .ndo_features_check     = mlx4_en_features_check,
++#endif
 +#ifdef HAVE_NDO_SET_TX_MAXRATE
        .ndo_set_tx_maxrate     = mlx4_en_set_tx_maxrate,
 +#endif
 +#ifdef HAVE_FILTER_XDP
        .ndo_xdp                = mlx4_xdp,
 +#endif
++};
++
++#ifdef HAVE_NET_DEVICE_OPS_EXT
++static const struct net_device_ops_ext mlx4_netdev_ops_ext = {
++      .size             = sizeof(struct net_device_ops_ext),
++      .ndo_set_features = mlx4_en_set_features,
++#ifdef HAVE_NETDEV_EXT_NDO_GET_PHYS_PORT_ID
++      .ndo_get_phys_port_id   = mlx4_en_get_phys_port_id,
++#endif
++};
++
++static const struct net_device_ops_ext mlx4_netdev_ops_master_ext = {
++      .size                   = sizeof(struct net_device_ops_ext),
++#ifdef HAVE_NETDEV_OPS_EXT_NDO_SET_VF_SPOOFCHK
++      .ndo_set_vf_spoofchk    = mlx4_en_set_vf_spoofchk,
++#endif
++#ifdef HAVE_NETDEV_OPS_EXT_NDO_SET_VF_LINK_STATE
++      .ndo_set_vf_link_state  = mlx4_en_set_vf_link_state,
++#endif
++#ifdef HAVE_NETDEV_EXT_NDO_GET_PHYS_PORT_ID
++      .ndo_get_phys_port_id   = mlx4_en_get_phys_port_id,
++#endif
++      .ndo_set_features       = mlx4_en_set_features,
  };
++#endif
++
  
  struct mlx4_en_bond {
-@@ -2794,6 +2940,7 @@ struct mlx4_en_bond {
+       struct work_struct work;
+@@ -2794,6 +2987,7 @@ struct mlx4_en_bond {
        struct mlx4_port_map port_map;
  };
  
@@ -1312,7 +1812,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  static void mlx4_en_bond_work(struct work_struct *work)
  {
        struct mlx4_en_bond *bond = container_of(work,
-@@ -2960,6 +3107,7 @@ int mlx4_en_netdev_event(struct notifier_block *this,
+@@ -2960,6 +3154,7 @@ int mlx4_en_netdev_event(struct notifier_block *this,
  
        return NOTIFY_DONE;
  }
@@ -1320,7 +1820,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  
  void mlx4_en_update_pfc_stats_bitmap(struct mlx4_dev *dev,
                                     struct mlx4_en_stats_bitmap *stats_bitmap,
-@@ -3050,12 +3198,20 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3050,12 +3245,20 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        int i;
        int err;
  
@@ -1341,7 +1841,28 @@ index xxxxxxx..xxxxxxx xxxxxx
        netif_set_real_num_rx_queues(dev, prof->rx_ring_num);
  
        SET_NETDEV_DEV(dev, &mdev->dev->persist->pdev->dev);
-@@ -3189,7 +3345,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3074,8 +3277,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+       INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
+       INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);
+       INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task);
++#if defined(HAVE_VXLAN_ENABLED) || defined(HAVE_UDP_TUNNEL_GET_RX_INFO)
+       INIT_WORK(&priv->vxlan_add_task, mlx4_en_add_vxlan_offloads);
+       INIT_WORK(&priv->vxlan_del_task, mlx4_en_del_vxlan_offloads);
++#endif
+ #ifdef CONFIG_RFS_ACCEL
+       INIT_LIST_HEAD(&priv->filters);
+       spin_lock_init(&priv->filters_lock);
+@@ -3094,7 +3299,9 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+       priv->num_tx_rings_p_up = mdev->profile.num_tx_rings_p_up;
+       priv->tx_ring_num = prof->tx_ring_num;
+       priv->tx_work_limit = MLX4_EN_DEFAULT_TX_WORK;
++#ifdef HAVE_NETDEV_RSS_KEY_FILL
+       netdev_rss_key_fill(priv->rss_key, sizeof(priv->rss_key));
++#endif
+       priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring *) * MAX_TX_RINGS,
+                               GFP_KERNEL);
+@@ -3189,7 +3396,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        else
                dev->netdev_ops = &mlx4_netdev_ops;
        dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
@@ -1353,15 +1874,26 @@ index xxxxxxx..xxxxxxx xxxxxx
        netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
  
        dev->ethtool_ops = &mlx4_en_ethtool_ops;
-@@ -3257,6 +3417,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3245,6 +3456,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+       if (mdev->dev->caps.steering_mode != MLX4_STEERING_MODE_A0)
+               dev->priv_flags |= IFF_UNICAST_FLT;
++#ifdef HAVE_ETH_SS_RSS_HASH_FUNCS
+       /* Setting a default hash function value */
+       if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_TOP) {
+               priv->rss_hash_fn = ETH_RSS_HASH_TOP;
+@@ -3255,8 +3467,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+                       "No RSS hash capabilities exposed, using Toeplitz\n");
+               priv->rss_hash_fn = ETH_RSS_HASH_TOP;
        }
++#endif
  
        if (mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) {
 +#ifdef HAVE_NET_DEVICE_GSO_PARTIAL_FEATURES
                dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
                                    NETIF_F_GSO_UDP_TUNNEL_CSUM |
                                    NETIF_F_GSO_PARTIAL;
-@@ -3264,6 +3425,12 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3264,6 +3478,12 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
                                    NETIF_F_GSO_UDP_TUNNEL_CSUM |
                                    NETIF_F_GSO_PARTIAL;
                dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
@@ -1374,7 +1906,7 @@ index xxxxxxx..xxxxxxx xxxxxx
        }
  
        mdev->pndev[port] = dev;
-@@ -3327,8 +3494,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3327,8 +3547,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        }
  
        priv->registered = 1;
@@ -1525,7 +2057,33 @@ index xxxxxxx..xxxxxxx xxxxxx
  
                if (likely(dev->features & NETIF_F_RXCSUM)) {
                        if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_TCP |
-@@ -1068,7 +1099,9 @@ next:
+@@ -977,7 +1008,11 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
+                       gro_skb->ip_summed = ip_summed;
+                       if (l2_tunnel && ip_summed == CHECKSUM_UNNECESSARY)
++#ifdef HAVE_SK_BUFF_CSUM_LEVEL
+                               gro_skb->csum_level = 1;
++#else
++                              gro_skb->encapsulation = 1;
++#endif
+                       if ((cqe->vlan_my_qpn &
+                           cpu_to_be32(MLX4_CQE_CVLAN_PRESENT_MASK)) &&
+@@ -1037,8 +1072,13 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
+               skb->protocol = eth_type_trans(skb, dev);
+               skb_record_rx_queue(skb, cq->ring);
++#ifdef HAVE_SK_BUFF_CSUM_LEVEL
+               if (l2_tunnel && ip_summed == CHECKSUM_UNNECESSARY)
+                       skb->csum_level = 1;
++#else
++              if (l2_tunnel)
++                      skb->encapsulation = 1;
++#endif
+               if (dev->features & NETIF_F_RXHASH)
+                       skb_set_hash(skb,
+@@ -1068,7 +1108,9 @@ next:
                for (nr = 0; nr < priv->num_frags; nr++)
                        mlx4_en_free_frag(priv, frags, nr);
  
@@ -1535,7 +2093,7 @@ index xxxxxxx..xxxxxxx xxxxxx
                ++cq->mcq.cons_index;
                index = (cq->mcq.cons_index) & ring->size_mask;
                cqe = mlx4_en_get_cqe(cq->buf, index, priv->cqe_size) + factor;
-@@ -1077,8 +1110,10 @@ consumed:
+@@ -1077,8 +1119,10 @@ consumed:
        }
  
  out:
@@ -1546,7 +2104,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  
        AVG_PERF_COUNTER(priv->pstats.rx_coal_avg, polled);
        mlx4_cq_set_ci(&cq->mcq);
-@@ -1114,14 +1149,20 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
+@@ -1114,14 +1158,20 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
        /* If we used up all the quota - we're probably not done yet... */
        if (done == budget) {
                const struct cpumask *aff;
@@ -1567,7 +2125,19 @@ index xxxxxxx..xxxxxxx xxxxxx
  
                if (likely(cpumask_test_cpu(cpu_curr, aff)))
                        return budget;
-@@ -1155,6 +1196,7 @@ void mlx4_en_calc_rx_buf(struct net_device *dev)
+@@ -1133,7 +1183,11 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
+               done = 0;
+       }
+       /* Done for now */
++#ifdef HAVE_NAPI_COMPLETE_DONE
+       napi_complete_done(napi, done);
++#else
++      napi_complete(napi);
++#endif
+       mlx4_en_arm_cq(priv, cq);
+       return done;
+ }
+@@ -1155,6 +1209,7 @@ void mlx4_en_calc_rx_buf(struct net_device *dev)
        int buf_size = 0;
        int i = 0;
  
@@ -1575,7 +2145,7 @@ index xxxxxxx..xxxxxxx xxxxxx
        /* bpf requires buffers to be set up as 1 packet per page.
         * This only works when num_frags == 1.
         */
-@@ -1166,6 +1208,7 @@ void mlx4_en_calc_rx_buf(struct net_device *dev)
+@@ -1166,6 +1221,7 @@ void mlx4_en_calc_rx_buf(struct net_device *dev)
                align = PAGE_SIZE;
                order = 0;
        }
@@ -1583,6 +2153,22 @@ index xxxxxxx..xxxxxxx xxxxxx
  
        while (buf_size < eff_mtu) {
                priv->frag_info[i].order = order;
+@@ -1343,6 +1399,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
+       rss_context->flags = rss_mask;
+       rss_context->hash_fn = MLX4_RSS_HASH_TOP;
++#ifdef HAVE_ETH_SS_RSS_HASH_FUNCS
+       if (priv->rss_hash_fn == ETH_RSS_HASH_XOR) {
+               rss_context->hash_fn = MLX4_RSS_HASH_XOR;
+       } else if (priv->rss_hash_fn == ETH_RSS_HASH_TOP) {
+@@ -1354,6 +1411,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
+               err = -EINVAL;
+               goto indir_err;
+       }
++#endif
+       err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context,
+                              &rss_map->indir_qp, &rss_map->indir_state);
+       if (err)
 diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
 index xxxxxxx..xxxxxxx xxxxxx
 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -1716,7 +2302,19 @@ index xxxxxxx..xxxxxxx xxxxxx
  
        /* Track current inflight packets for performance analysis */
        AVG_PERF_COUNTER(priv->pstats.inflight_avg,
-@@ -1078,6 +1122,7 @@ tx_drop:
+@@ -1030,7 +1074,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
+               netif_tx_stop_queue(ring->tx_queue);
+               ring->queue_stopped++;
+       }
++#ifdef HAVE_SK_BUFF_XMIT_MORE
+       send_doorbell = !skb->xmit_more || netif_xmit_stopped(ring->tx_queue);
++#else
++      send_doorbell = true;
++#endif
+       real_size = (real_size / 16) & 0x3f;
+@@ -1078,6 +1126,7 @@ tx_drop:
        return NETDEV_TX_OK;
  }
  
@@ -1724,7 +2322,7 @@ index xxxxxxx..xxxxxxx xxxxxx
  netdev_tx_t mlx4_en_xmit_frame(struct mlx4_en_rx_alloc *frame,
                               struct net_device *dev, unsigned int length,
                               int tx_ind, int *doorbell_pending)
-@@ -1182,3 +1227,4 @@ tx_drop_count:
+@@ -1182,3 +1231,4 @@ tx_drop_count:
  tx_drop:
        return NETDEV_TX_BUSY;
  }
@@ -2100,3 +2698,34 @@ index xxxxxxx..xxxxxxx xxxxxx
                if (!uar->bf_map) {
                        err = -ENOMEM;
                        goto unamp_uar;
+diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
+index xxxxxxx..xxxxxxx xxxxxx
+--- a/include/linux/mlx4/cmd.h
++++ b/include/linux/mlx4/cmd.h
+@@ -305,8 +305,10 @@ void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbo
+ int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
+                          struct mlx4_counter *counter_stats, int reset);
++#ifdef HAVE_NDO_GET_VF_STATS
+ int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
+                     struct ifla_vf_stats *vf_stats);
++#endif
+ u32 mlx4_comm_get_version(void);
+ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac);
+ int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos);
+diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
+index xxxxxxx..xxxxxxx xxxxxx
+--- a/include/linux/mlx4/device.h
++++ b/include/linux/mlx4/device.h
+@@ -42,7 +42,11 @@
+ #include <linux/atomic.h>
++#ifdef HAVE_TIMECOUNTER_H
+ #include <linux/timecounter.h>
++#else
++#include <linux/clocksource.h>
++#endif
+ #define DEFAULT_UAR_PAGE_SHIFT  12