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
#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;
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;
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
+ 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;
+ }
+}
+#endif
-
++
+#ifdef HAVE_ETHTOOL_xLINKSETTINGS
static int
mlx4_en_get_link_ksettings(struct net_device *dev,
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);
+ 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;
}
+ 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
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
*/
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;
/* 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;
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;
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;
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);
+ 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:
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;
}
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,
.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
/* 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;
}
{
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)
}
{
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) {
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;
}
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);
}
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
{
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 */
}
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 */
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;
}
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);
}
+}
+#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
¶ms);
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;
}
}
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,
+ .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
};
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
#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
+ .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;
};
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;
}
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;
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;
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;
}
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;
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);
++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:
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;
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;
/* 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;
}
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
/* 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;
}
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;
}
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
+