From: Valentine Fatiev <valentinef@nvidia.com>
Subject: [PATCH] BACKPORT: drivers/infiniband/ulp/ipoib/ipoib_ib.c

Change-Id: Ic81685f953875a8a35286e87f69d905d81dfefac
---
 drivers/infiniband/ulp/ipoib/ipoib_ib.c | 67 ++++++++++++++++++++++---
 1 file changed, 59 insertions(+), 8 deletions(-)

--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -202,7 +202,6 @@ static inline void ipoib_create_repath_e
 	else
 		kfree(arp_repath);
 }
-
 static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
 {
 	struct ipoib_dev_priv *priv = ipoib_priv(dev);
@@ -283,7 +282,6 @@ static void ipoib_ib_handle_rx_wc(struct
 	}
 
 	skb_pull(skb, IB_GRH_BYTES);
-
 	skb->protocol = ((struct ipoib_header *) skb->data)->proto;
 	skb_add_pseudo_hdr(skb);
 
@@ -299,8 +297,14 @@ static void ipoib_ib_handle_rx_wc(struct
 	if ((dev->features & NETIF_F_RXCSUM) &&
 			likely(wc->wc_flags & IB_WC_IP_CSUM_OK))
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
-
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+	if (dev->features & NETIF_F_LRO)
+		lro_receive_skb(&priv->lro.lro_mgr, skb, NULL);
+	else
+		netif_receive_skb(skb);
+#else
 	napi_gro_receive(&priv->recv_napi, skb);
+#endif
 
 repost:
 	if (unlikely(ipoib_ib_post_receive(dev, wr_id)))
@@ -329,8 +333,12 @@ int ipoib_dma_map_tx(struct ib_device *c
 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 		mapping[i + off] = ib_dma_map_page(ca,
 						 skb_frag_page(frag),
-						 skb_frag_off(frag),
-						 skb_frag_size(frag),
+#ifdef HAVE_SKB_FRAG_OFF
+	       					 skb_frag_off(frag),
+       						 skb_frag_size(frag),
+#else
+						 frag->page_offset, skb_frag_size(frag),
+#endif
 						 DMA_TO_DEVICE);
 		if (unlikely(ib_dma_mapping_error(ca, mapping[i + off])))
 			goto partial_error;
@@ -521,11 +529,19 @@ poll_more:
 	}
 
 	if (done < budget) {
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+		if (dev->features & NETIF_F_LRO)
+			lro_flush_all(&priv->lro.lro_mgr);
+#endif
 		napi_complete(napi);
 		if (unlikely(ib_req_notify_cq(priv->recv_cq,
 					      IB_CQ_NEXT_COMP |
 					      IB_CQ_REPORT_MISSED_EVENTS)) &&
-		    napi_schedule(napi))
+#ifdef HAVE_NAPI_RESCHEDULE
+			napi_reschedule(napi))
+#else
+			napi_schedule(napi))
+#endif
 			goto poll_more;
 	}
 
@@ -555,7 +571,11 @@ poll_more:
 		napi_complete(napi);
 		if (unlikely(ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP |
 					      IB_CQ_REPORT_MISSED_EVENTS)) &&
-		    napi_schedule(napi))
+#ifdef HAVE_NAPI_RESCHEDULE
+			napi_reschedule(napi))
+#else
+			napi_schedule(napi))
+#endif
 			goto poll_more;
 	}
 	return n < 0 ? 0 : n;
@@ -565,7 +585,11 @@ void ipoib_ib_rx_completion(struct ib_cq
 {
 	struct ipoib_dev_priv *priv = ctx_ptr;
 
-	napi_schedule(&priv->recv_napi);
+#ifdef HAVE_NAPI_RESCHEDULE
+       napi_reschedule(&priv->recv_napi);
+#else
+       napi_schedule(&priv->recv_napi);
+#endif
 }
 
 /* The function will force napi_schedule */
@@ -576,7 +600,11 @@ void ipoib_napi_schedule_work(struct wor
 	bool ret;
 
 	do {
+#ifdef HAVE_NAPI_RESCHEDULE
+		ret = napi_reschedule(&priv->send_napi);
+#else
 		ret = napi_schedule(&priv->send_napi);
+#endif
 		if (!ret)
 			msleep(3);
 	} while (!ret && netif_queue_stopped(priv->dev) &&
@@ -588,7 +616,11 @@ void ipoib_ib_tx_completion(struct ib_cq
 	struct ipoib_dev_priv *priv = ctx_ptr;
 	bool ret;
 
+#ifdef HAVE_NAPI_RESCHEDULE
+	ret = napi_reschedule(&priv->send_napi);
+#else
 	ret = napi_schedule(&priv->send_napi);
+#endif
 	/*
 	 * if the queue is closed the driver must be able to schedule napi,
 	 * otherwise we can end with closed queue forever, because no new
@@ -640,7 +672,11 @@ int ipoib_send(struct net_device *dev, s
 	unsigned int usable_sge = priv->max_send_sge - !!skb_headlen(skb);
 
 	if (skb_is_gso(skb)) {
+#ifdef HAVE_SKB_TCP_ALL_HEADERS
 		hlen = skb_tcp_all_headers(skb);
+#else
+		hlen = skb_transport_offset(skb) + tcp_hdrlen(skb);
+#endif
 		phead = skb->data;
 		if (unlikely(!skb_pull(skb, hlen))) {
 			ipoib_warn(priv, "linear data too small\n");
@@ -1141,11 +1177,17 @@ static bool ipoib_dev_addr_changed_valid
 {
 	union ib_gid search_gid;
 	union ib_gid gid0;
+#ifndef HAVE_DEV_ADDR_MOD
+	union ib_gid *netdev_gid;
+#endif
 	int err;
 	u16 index;
 	u32 port;
 	bool ret = false;
 
+#ifndef HAVE_DEV_ADDR_MOD
+	netdev_gid = (union ib_gid *)(priv->dev->dev_addr + 4);
+#endif
 	if (rdma_query_gid(priv->ca, priv->port, 0, &gid0))
 		return false;
 
@@ -1155,8 +1197,12 @@ static bool ipoib_dev_addr_changed_valid
 	 * to do it later
 	 */
 	priv->local_gid.global.subnet_prefix = gid0.global.subnet_prefix;
+#ifdef HAVE_DEV_ADDR_MOD
 	dev_addr_mod(priv->dev, 4, (u8 *)&gid0.global.subnet_prefix,
 		     sizeof(gid0.global.subnet_prefix));
+#else
+	netdev_gid->global.subnet_prefix = gid0.global.subnet_prefix;
+#endif
 	search_gid.global.subnet_prefix = gid0.global.subnet_prefix;
 
 	search_gid.global.interface_id = priv->local_gid.global.interface_id;
@@ -1218,8 +1264,13 @@ static bool ipoib_dev_addr_changed_valid
 			if (!test_bit(IPOIB_FLAG_DEV_ADDR_CTRL, &priv->flags)) {
 				memcpy(&priv->local_gid, &gid0,
 				       sizeof(priv->local_gid));
+#ifdef HAVE_DEV_ADDR_MOD
 				dev_addr_mod(priv->dev, 4, (u8 *)&gid0,
 					     sizeof(priv->local_gid));
+#else
+				memcpy(priv->dev->dev_addr + 4, &gid0,
+				       sizeof(priv->local_gid));
+#endif
 				ret = true;
 			}
 		}
