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

Change-Id: I183263414706486820000fcd8fa0e4f127a86042
---
 drivers/infiniband/ulp/ipoib/ipoib_ib.c | 37 +++++++++++++++++++++----
 1 file changed, 32 insertions(+), 5 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,6 +529,10 @@ 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 |
@@ -1141,11 +1153,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 +1173,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 +1240,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;
 			}
 		}
