From: Valentine Fatiev <valentinef@nvidia.com>
Subject: [PATCH] BACKPORT: drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c

Change-Id: I16d1870660bdd48baa6c1e7242c23a00f07a3f9d
---
 .../net/ethernet/mellanox/mlx5/core/lag/mp.c  | 74 ++++++++++++++++++-
 1 file changed, 71 insertions(+), 3 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c
@@ -2,13 +2,21 @@
 /* Copyright (c) 2019 Mellanox Technologies. */
 
 #include <linux/netdevice.h>
+#ifdef HAVE_FIB_INFO_NH
 #include <net/nexthop.h>
-#include "lag/lag.h"
-#include "lag/mp.h"
+#endif
 #include "mlx5_core.h"
 #include "eswitch.h"
 #include "lib/mlx5.h"
 
+#if defined(MLX_USE_LAG_COMPAT) || defined(HAVE_LAG_TX_TYPE)
+#define MLX_LAG_SUPPORTED
+#endif
+
+#ifdef MLX_LAG_SUPPORTED
+#include "lag.h"
+
+#ifdef HAVE_FIB_NH_NOTIFIER_INFO
 static bool __mlx5_lag_is_multipath(struct mlx5_lag *ldev)
 {
 	return !!(ldev->flags & MLX5_LAG_FLAG_MULTIPATH);
@@ -36,6 +44,7 @@ bool mlx5_lag_is_multipath(struct mlx5_c
 
 	return res;
 }
+#endif
 
 /**
  * mlx5_lag_set_port_affinity
@@ -47,6 +56,7 @@ bool mlx5_lag_is_multipath(struct mlx5_c
  *     2 - set affinity to port 2.
  *
  **/
+#ifdef HAVE_FIB_NH_NOTIFIER_INFO
 static void mlx5_lag_set_port_affinity(struct mlx5_lag *ldev,
 				       enum mlx5_lag_port_affinity port)
 {
@@ -141,11 +151,23 @@ static void mlx5_lag_fib_route_event(str
 		return;
 
 	/* Handle add/replace event */
+#ifdef HAVE_FIB_INFO_NH
 	nhs = fib_info_num_path(fi);
+#else
+	nhs = fi->fib_nhs;
+#endif
 	if (nhs == 1) {
 		if (__mlx5_lag_is_active(ldev)) {
+#ifdef HAVE_FIB_INFO_NH
 			struct fib_nh *nh = fib_info_nh(fi, 0);
 			struct net_device *nh_dev = nh->fib_nh_dev;
+#else
+#ifdef HAVE_FIB_NH_DEV
+			struct net_device *nh_dev = fi->fib_nh[0].fib_nh_dev;
+#else
+			struct net_device *nh_dev = fi->fib_nh[0].nh_dev;
+#endif
+#endif
 			int i = mlx5_lag_dev_get_netdev_idx(ldev, nh_dev);
 
 			if (i < 0)
@@ -163,12 +185,28 @@ static void mlx5_lag_fib_route_event(str
 		return;
 
 	/* Verify next hops are ports of the same hca */
+#ifdef HAVE_FIB_INFO_NH
 	fib_nh0 = fib_info_nh(fi, 0);
 	fib_nh1 = fib_info_nh(fi, 1);
 	if (!(fib_nh0->fib_nh_dev == ldev->pf[MLX5_LAG_P1].netdev &&
 	      fib_nh1->fib_nh_dev == ldev->pf[MLX5_LAG_P2].netdev) &&
 	    !(fib_nh0->fib_nh_dev == ldev->pf[MLX5_LAG_P2].netdev &&
 	      fib_nh1->fib_nh_dev == ldev->pf[MLX5_LAG_P1].netdev)) {
+#else
+	fib_nh0 = &fi->fib_nh[0];
+	fib_nh1 = &fi->fib_nh[1];
+#ifdef HAVE_FIB_NH_DEV
+	if (!(fib_nh0->fib_nh_dev == ldev->pf[MLX5_LAG_P1].netdev &&
+	      fib_nh1->fib_nh_dev == ldev->pf[MLX5_LAG_P2].netdev) &&
+	    !(fib_nh0->fib_nh_dev == ldev->pf[MLX5_LAG_P2].netdev &&
+	      fib_nh1->fib_nh_dev == ldev->pf[MLX5_LAG_P1].netdev)) {
+#else
+	if (!(fib_nh0->nh_dev == ldev->pf[MLX5_LAG_P1].netdev &&
+	      fib_nh1->nh_dev == ldev->pf[MLX5_LAG_P2].netdev) &&
+	    !(fib_nh0->nh_dev == ldev->pf[MLX5_LAG_P2].netdev &&
+	      fib_nh1->nh_dev == ldev->pf[MLX5_LAG_P1].netdev)) {
+#endif
+#endif
 		mlx5_core_warn(ldev->pf[MLX5_LAG_P1].dev,
 			       "Multipath offload require two ports of the same HCA\n");
 		return;
@@ -202,14 +240,22 @@ static void mlx5_lag_fib_nexthop_event(s
 
 	/* nh added/removed */
 	if (event == FIB_EVENT_NH_DEL) {
+#ifdef HAVE_FIB_NH_DEV
 		int i = mlx5_lag_dev_get_netdev_idx(ldev, fib_nh->fib_nh_dev);
+#else
+		int i = mlx5_lag_dev_get_netdev_idx(ldev, fib_nh->nh_dev);
+#endif
 
 		if (i >= 0) {
 			i = (i + 1) % 2 + 1; /* peer port */
 			mlx5_lag_set_port_affinity(ldev, i);
 		}
 	} else if (event == FIB_EVENT_NH_ADD &&
+#ifdef HAVE_FIB_INFO_NH
 		   fib_info_num_path(fi) == 2) {
+#else
+		   fi->fib_nhs == 2) {
+#endif
 		mlx5_lag_set_port_affinity(ldev, MLX5_LAG_NORMAL_AFFINITY);
 	}
 }
@@ -225,6 +271,8 @@ static void mlx5_lag_fib_update(struct w
 	rtnl_lock();
 	switch (fib_work->event) {
 	case FIB_EVENT_ENTRY_REPLACE:
+	case FIB_EVENT_ENTRY_APPEND: /* fall through */
+	case FIB_EVENT_ENTRY_ADD: /* fall through */
 	case FIB_EVENT_ENTRY_DEL:
 		mlx5_lag_fib_route_event(ldev, fib_work->event,
 					 &fib_work->fen_info);
@@ -271,8 +319,10 @@ static int mlx5_lag_fib_event(struct not
 	struct mlx5_fib_event_work *fib_work;
 	struct fib_entry_notifier_info *fen_info;
 	struct fib_nh_notifier_info *fnh_info;
-	struct net_device *fib_dev;
 	struct fib_info *fi;
+#ifdef HAVE_FIB_INFO_NH
+	struct net_device *fib_dev;
+#endif
 
 	if (info->family != AF_INET)
 		return NOTIFY_DONE;
@@ -282,15 +332,22 @@ static int mlx5_lag_fib_event(struct not
 
 	switch (event) {
 	case FIB_EVENT_ENTRY_REPLACE:
+	case FIB_EVENT_ENTRY_APPEND: /* fall through */
+	case FIB_EVENT_ENTRY_ADD: /* fall through */
 	case FIB_EVENT_ENTRY_DEL:
 		fen_info = container_of(info, struct fib_entry_notifier_info,
 					info);
 		fi = fen_info->fi;
+#ifdef HAVE_FIB_INFO_NH
 		if (fi->nh)
 			return NOTIFY_DONE;
 		fib_dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev;
 		if (fib_dev != ldev->pf[MLX5_LAG_P1].netdev &&
 		    fib_dev != ldev->pf[MLX5_LAG_P2].netdev) {
+#else
+		if (fi->fib_dev != ldev->pf[MLX5_LAG_P1].netdev &&
+		    fi->fib_dev != ldev->pf[MLX5_LAG_P2].netdev) {
+#endif
 			return NOTIFY_DONE;
 		}
 		fib_work = mlx5_lag_init_fib_work(ldev, event);
@@ -347,8 +404,13 @@ int mlx5_lag_mp_init(struct mlx5_lag *ld
 		return -ENOMEM;
 
 	mp->fib_nb.notifier_call = mlx5_lag_fib_event;
+#ifdef HAVE_REGISTER_FIB_NOTIFIER_HAS_4_PARAMS
 	err = register_fib_notifier(&init_net, &mp->fib_nb,
 				    mlx5_lag_fib_event_flush, NULL);
+#else
+	err = register_fib_notifier(&mp->fib_nb,
+				    mlx5_lag_fib_event_flush);
+#endif
 	if (err) {
 		destroy_workqueue(mp->wq);
 		mp->fib_nb.notifier_call = NULL;
@@ -364,8 +426,14 @@ void mlx5_lag_mp_cleanup(struct mlx5_lag
 	if (!mp->fib_nb.notifier_call)
 		return;
 
+#ifdef HAVE_REGISTER_FIB_NOTIFIER_HAS_4_PARAMS
 	unregister_fib_notifier(&init_net, &mp->fib_nb);
+#else
+	unregister_fib_notifier(&mp->fib_nb);
+#endif
 	destroy_workqueue(mp->wq);
 	mp->fib_nb.notifier_call = NULL;
 	mp->fib.mfi = NULL;
 }
+#endif /* HAVE_FIB_NH_NOTIFIER_INFO */
+#endif /* MLX_LAG_SUPPORTED */
