--- /dev/null
+RDMA/nes: Backport patch for RHEL6.4, RHEL6.5 and SLES11 SP3
+
+Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
+---
+ drivers/infiniband/hw/nes/nes.c | 4 ++
+ drivers/infiniband/hw/nes/nes_cm.c | 14 +++++-
+ drivers/infiniband/hw/nes/nes_hw.c | 28 +++++++++--
+ drivers/infiniband/hw/nes/nes_hw.h | 6 ++
+ drivers/infiniband/hw/nes/nes_nic.c | 96 ++++++++++++++++++++++++++++++++--
+ 5 files changed, 137 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
+index 4291410..570b0f5 100644
+--- a/drivers/infiniband/hw/nes/nes.c
++++ b/drivers/infiniband/hw/nes/nes.c
+@@ -146,7 +146,11 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
+ nesdev, nesdev->netdev[0]->name);
+ netdev = nesdev->netdev[0];
+ nesvnic = netdev_priv(netdev);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
+ upper_dev = netdev_master_upper_dev_get(netdev);
++#else
++ upper_dev = netdev->master;
++#endif
+ is_bonded = netif_is_bond_slave(netdev) &&
+ (upper_dev == event_netdev);
+ if ((netdev == event_netdev) || is_bonded) {
+diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
+index 6b29249..18c3162 100644
+--- a/drivers/infiniband/hw/nes/nes_cm.c
++++ b/drivers/infiniband/hw/nes/nes_cm.c
+@@ -1331,16 +1331,28 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
+ int rc = arpindex;
+ struct net_device *netdev;
+ struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)
++ struct flowi fl;
+
++ memset(&fl, 0, sizeof fl);
++ fl.nl_u.ip4_u.daddr = htonl(dst_ip);
++ if (ip_route_output_key(&init_net, &rt, &fl)) {
++#else
+ rt = ip_route_output(&init_net, htonl(dst_ip), 0, 0, 0);
+ if (IS_ERR(rt)) {
++#endif
+ printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n",
+ __func__, dst_ip);
+ return rc;
+ }
+
+- if (netif_is_bond_slave(nesvnic->netdev))
++ if (netif_is_bond_slave(nesvnic->netdev)) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
+ netdev = netdev_master_upper_dev_get(nesvnic->netdev);
++#else
++ netdev = nesvnic->netdev->master;
++#endif
++ }
+ else
+ netdev = nesvnic->netdev;
+
+diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
+index 9020024..86afebb 100644
+--- a/drivers/infiniband/hw/nes/nes_hw.c
++++ b/drivers/infiniband/hw/nes/nes_hw.c
+@@ -2909,7 +2909,11 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
+ if ((cqe_errv &
+ (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR |
+ NES_NIC_ERRV_BITS_IPH_ERR | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
++ if (nesvnic->rx_checksum_disabled == 0)
++#else
+ if (nesvnic->netdev->features & NETIF_F_RXCSUM)
++#endif
+ rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else
+ nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet."
+@@ -2920,11 +2924,12 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
+ if ((cqe_errv &
+ (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_IPH_ERR |
+ NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
+- if (nesvnic->netdev->features & NETIF_F_RXCSUM) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
++ if (nesvnic->rx_checksum_disabled == 0)
++#else
++ if (nesvnic->netdev->features & NETIF_F_RXCSUM)
++#endif
+ rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
+- /* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n",
+- nesvnic->netdev->name); */
+- }
+ } else
+ nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet."
+ " errv = 0x%X, pkt_type = 0x%X.\n",
+@@ -2948,7 +2953,22 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
+ nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
+ nesvnic->netdev->name, vlan_tag);
+
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0))
++ if (nesvnic->vlan_grp != NULL) {
++ if (nes_use_lro)
++ lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb,
++ nesvnic->vlan_grp, vlan_tag, NULL);
++ else
++ vlan_hwaccel_receive_skb(rx_skb, nesvnic->vlan_grp, vlan_tag);
++ goto skip_rx_indicate0;
++ }
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
++ __vlan_hwaccel_put_tag(rx_skb, vlan_tag);
++#else
+ __vlan_hwaccel_put_tag(rx_skb, htons(ETH_P_8021Q), vlan_tag);
++#endif
+ }
+ if (nes_use_lro)
+ lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL);
+diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
+index d748e4b..72e5934 100644
+--- a/drivers/infiniband/hw/nes/nes_hw.h
++++ b/drivers/infiniband/hw/nes/nes_hw.h
+@@ -1269,6 +1269,12 @@ struct nes_vnic {
+ u8 next_qp_nic_index;
+ u8 of_device_registered;
+ u8 rdma_enabled;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)
++ struct vlan_group *vlan_grp;
++#endif
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
++ u8 rx_checksum_disabled;
++#endif
+ u32 lro_max_aggr;
+ struct net_lro_mgr lro_mgr;
+ struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS];
+diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
+index 49eb511..795d305 100644
+--- a/drivers/infiniband/hw/nes/nes_nic.c
++++ b/drivers/infiniband/hw/nes/nes_nic.c
+@@ -904,16 +904,24 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
+ if (!mc_all_on) {
+ char *addrs;
+ int i;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
+ struct netdev_hw_addr *ha;
+-
++#else
++ struct dev_mc_list *mcaddr;
++#endif
+ addrs = kmalloc(ETH_ALEN * mc_count, GFP_ATOMIC);
+ if (!addrs) {
+ set_allmulti(nesdev, nic_active_bit);
+ goto unlock;
+ }
+ i = 0;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
+ netdev_for_each_mc_addr(ha, netdev)
+ memcpy(get_addr(addrs, i++), ha->addr, ETH_ALEN);
++#else
++ netdev_for_each_mc_addr(mcaddr, netdev)
++ memcpy(get_addr(addrs, i++), mcaddr->dmi_addr, ETH_ALEN);
++#endif
+
+ perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW +
+ pft_entries_preallocated * 0x8;
+@@ -1572,6 +1580,34 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd
+ return 0;
+ }
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
++/**
++ * nes_netdev_get_rx_csum
++ */
++static u32 nes_netdev_get_rx_csum (struct net_device *netdev)
++{
++ struct nes_vnic *nesvnic = netdev_priv(netdev);
++
++ if (nesvnic->rx_checksum_disabled)
++ return 0;
++ else
++ return 1;
++}
++
++/**
++ * nes_netdev_set_rc_csum
++ */
++static int nes_netdev_set_rx_csum(struct net_device *netdev, u32 enable)
++{
++ struct nes_vnic *nesvnic = netdev_priv(netdev);
++
++ if (enable)
++ nesvnic->rx_checksum_disabled = 0;
++ else
++ nesvnic->rx_checksum_disabled = 1;
++ return 0;
++}
++#endif
+
+ static const struct ethtool_ops nes_ethtool_ops = {
+ .get_link = ethtool_op_get_link,
+@@ -1585,8 +1621,46 @@ static const struct ethtool_ops nes_ethtool_ops = {
+ .set_coalesce = nes_netdev_set_coalesce,
+ .get_pauseparam = nes_netdev_get_pauseparam,
+ .set_pauseparam = nes_netdev_set_pauseparam,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
++ .get_tx_csum = ethtool_op_get_tx_csum,
++ .set_tx_csum = ethtool_op_set_tx_csum,
++ .get_rx_csum = nes_netdev_get_rx_csum,
++ .set_rx_csum = nes_netdev_set_rx_csum,
++ .get_sg = ethtool_op_get_sg,
++ .set_sg = ethtool_op_set_sg,
++ .get_tso = ethtool_op_get_tso,
++ .set_tso = ethtool_op_set_tso,
++ .get_flags = ethtool_op_get_flags,
++ .set_flags = ethtool_op_set_flags
++#endif
+ };
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)
++static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
++{
++ struct nes_vnic *nesvnic = netdev_priv(netdev);
++ struct nes_device *nesdev = nesvnic->nesdev;
++ struct nes_adapter *nesadapter = nesdev->nesadapter;
++ u32 u32temp;
++ unsigned long flags;
++
++ spin_lock_irqsave(&nesadapter->phy_lock, flags);
++ nesvnic->vlan_grp = grp;
++
++ nes_debug(NES_DBG_NETDEV, "%s: %s\n", __func__, netdev->name);
++
++ /* Enable/Disable VLAN Stripping */
++ u32temp = nes_read_indexed(nesdev, NES_IDX_PCIX_DIAG);
++ if (grp)
++ u32temp &= 0xfdffffff;
++ else
++ u32temp |= 0x02000000;
++
++ nes_write_indexed(nesdev, NES_IDX_PCIX_DIAG, u32temp);
++ spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
++}
++#endif
++
+ static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev, netdev_features_t features)
+ {
+ struct nes_adapter *nesadapter = nesdev->nesadapter;
+@@ -1608,6 +1682,7 @@ static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev,
+ spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
+ }
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
+ static netdev_features_t nes_fix_features(struct net_device *netdev, netdev_features_t features)
+ {
+ /*
+@@ -1633,6 +1708,7 @@ static int nes_set_features(struct net_device *netdev, netdev_features_t feature
+
+ return 0;
+ }
++#endif
+
+ static const struct net_device_ops nes_netdev_ops = {
+ .ndo_open = nes_netdev_open,
+@@ -1644,8 +1720,13 @@ static const struct net_device_ops nes_netdev_ops = {
+ .ndo_set_rx_mode = nes_netdev_set_multicast_list,
+ .ndo_change_mtu = nes_netdev_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
+ .ndo_fix_features = nes_fix_features,
+ .ndo_set_features = nes_set_features,
++#endif
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)
++ .ndo_vlan_rx_register = nes_netdev_vlan_rx_register,
++#endif
+ };
+
+ /**
+@@ -1706,12 +1787,15 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
+ netdev->dev_addr[4] = (u8)(u64temp>>8);
+ netdev->dev_addr[5] = (u8)u64temp;
+
+- netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX;
+- if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV))
+- netdev->hw_features |= NETIF_F_TSO;
++ netdev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX;
++
++ if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV))
++ netdev->features |= NETIF_F_TSO;
+
+- netdev->features = netdev->hw_features | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX;
+- netdev->hw_features |= NETIF_F_LRO;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
++ netdev->hw_features |= netdev->features | NETIF_F_LRO;
++#endif
++ netdev->features |= NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX;
+
+ nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d,"
+ " nic_index = %d, logical_port = %d, mac_index = %d.\n",
+--
+1.7.1
+