]> git.openfabrics.org - ~tnikolova/compat-rdma/.git/commitdiff
cxgb4: Backports for RHEL6.2 RHEL6.3 and SLES11 SP2
authorVipul Pandya <vipul@chelsio.com>
Tue, 31 Jul 2012 09:57:53 +0000 (15:27 +0530)
committerVipul Pandya <vipul@chelsio.com>
Tue, 31 Jul 2012 10:15:27 +0000 (03:15 -0700)
Signed-off-by: Vipul Pandya <vipul@chelsio.com>
patches/0011-cxgb4-Backports-for-RHEL6.2-RHEL-6.3-and-SLES11-SP2.patch [new file with mode: 0644]

diff --git a/patches/0011-cxgb4-Backports-for-RHEL6.2-RHEL-6.3-and-SLES11-SP2.patch b/patches/0011-cxgb4-Backports-for-RHEL6.2-RHEL-6.3-and-SLES11-SP2.patch
new file mode 100644 (file)
index 0000000..2f5f8c5
--- /dev/null
@@ -0,0 +1,598 @@
+From 867d62561a8a95e35469b72b4c82589524e069b3 Mon Sep 17 00:00:00 2001
+From: Vipul Pandya <vipul@chelsio.com>
+Date: Mon, 30 Jul 2012 12:06:12 +0530
+Subject: [PATCH 1/4] cxgb4: Backports for RHEL6.2 RHEL 6.3 and SLES11 SP2
+
+Signed-off-by: Vipul Pandya <vipul@chelsio.com>
+---
+ drivers/net/ethernet/chelsio/cxgb4/cxgb4.h      |   13 ++
+ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |  190 ++++++++++++++++++++++-
+ drivers/net/ethernet/chelsio/cxgb4/sge.c        |   72 +++++++++-
+ 3 files changed, 273 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+index ec2dafe..84fa932 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+@@ -300,6 +300,9 @@ struct port_info {
+       u8     port_id;
+       u8     tx_chan;
+       u8     lport;                 /* associated offload logical port */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++      u8     rx_offload;            /* CSO, etc */
++#endif
+       u8     nqsets;                /* # of qsets */
+       u8     first_qset;            /* index of first qset */
+       u8     rss_mode;
+@@ -307,6 +310,12 @@ struct port_info {
+       u16   *rss;
+ };
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++/* port_info.rx_offload flags */
++enum {
++      RX_CSO = 1 << 0,
++};
++#endif
+ struct dentry;
+ struct work_struct;
+@@ -337,7 +346,11 @@ struct sge_fl {                     /* SGE free-buffer queue state */
+ /* A packet gather list */
+ struct pkt_gl {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+       struct page_frag frags[MAX_SKB_FRAGS];
++#else
++      skb_frag_t frags[MAX_SKB_FRAGS];
++#endif
+       void *va;                         /* virtual address of first byte */
+       unsigned int nfrags;              /* # of fragments */
+       unsigned int tot_len;             /* total length of fragments */
+diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+index e1f96fb..12a0dba 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+@@ -31,7 +31,9 @@
+  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  * SOFTWARE.
+  */
+-
++#ifdef pr_fmt
++#undef pr_fmt
++#endif
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+ #include <linux/bitmap.h>
+@@ -324,14 +326,25 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
+       u16 filt_idx[7];
+       const u8 *addr[7];
+       int ret, naddr = 0;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
++      const struct dev_addr_list *d;
++#endif
+       const struct netdev_hw_addr *ha;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+       int uc_cnt = netdev_uc_count(dev);
+       int mc_cnt = netdev_mc_count(dev);
++#else
++      int uc_cnt = ((&(dev)->uc)->count);
++#endif
+       const struct port_info *pi = netdev_priv(dev);
+       unsigned int mb = pi->adapter->fn;
+       /* first do the secondary unicast addresses */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+       netdev_for_each_uc_addr(ha, dev) {
++#else
++      list_for_each_entry(ha, &(&(dev)->uc)->list, list) {
++#endif
+               addr[naddr++] = ha->addr;
+               if (--uc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) {
+                       ret = t4_alloc_mac_filt(pi->adapter, mb, pi->viid, free,
+@@ -345,9 +358,15 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
+       }
+       /* next set up the multicast addresses */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+       netdev_for_each_mc_addr(ha, dev) {
+               addr[naddr++] = ha->addr;
+               if (--mc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) {
++#else
++      netdev_for_each_mc_addr(d, dev) {
++              addr[naddr++] = d->dmi_addr;
++              if (naddr >= ARRAY_SIZE(addr) || d->next == NULL) {
++#endif
+                       ret = t4_alloc_mac_filt(pi->adapter, mb, pi->viid, free,
+                                       naddr, addr, filt_idx, &mhash, sleep);
+                       if (ret < 0)
+@@ -1537,6 +1556,26 @@ static int set_pauseparam(struct net_device *dev,
+       return 0;
+ }
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++static u32 get_rx_csum(struct net_device *dev)
++{
++      struct port_info *p = netdev_priv(dev);
++
++      return p->rx_offload & RX_CSO;
++}
++
++static int set_rx_csum(struct net_device *dev, u32 data)
++{
++      struct port_info *p = netdev_priv(dev);
++
++      if (data)
++              p->rx_offload |= RX_CSO;
++      else
++              p->rx_offload &= ~RX_CSO;
++      return 0;
++}
++#endif
++
+ static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
+ {
+       const struct port_info *pi = netdev_priv(dev);
+@@ -1858,10 +1897,19 @@ static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+       return err;
+ }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+ static int cxgb_set_features(struct net_device *dev, netdev_features_t features)
++#else
++static int cxgb_set_features(struct net_device *dev, u32 features)
++#endif
+ {
+       const struct port_info *pi = netdev_priv(dev);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+       netdev_features_t changed = dev->features ^ features;
++#else
++      u32 changed = dev->features ^ features;
++#endif
+       int err;
+       if (!(changed & NETIF_F_HW_VLAN_RX))
+@@ -1874,14 +1922,55 @@ static int cxgb_set_features(struct net_device *dev, netdev_features_t features)
+               dev->features = features ^ NETIF_F_HW_VLAN_RX;
+       return err;
+ }
++#else
++#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
++static int set_tso(struct net_device *dev, u32 value)
++{
++      if (value)
++              dev->features |= TSO_FLAGS;
++      else
++              dev->features &= ~TSO_FLAGS;
++      return 0;
++}
++
++static int set_flags(struct net_device *dev, u32 flags)
++{
++      int err;
++      unsigned long old_feat = dev->features;
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
++      err = ethtool_op_set_flags(dev, flags, ETH_FLAG_RXHASH |
++                      ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
++#else
++      err = ethtool_op_set_flags(dev, flags);
++#endif
++      if (err)
++              return err;
++
++      if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX) {
++              const struct port_info *pi = netdev_priv(dev);
++
++              err = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1,
++                              -1, -1, -1, !!(flags & ETH_FLAG_RXVLAN),
++                              true);
++              if (err)
++                      dev->features = old_feat;
++      }
++      return err;
++}
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+ static u32 get_rss_table_size(struct net_device *dev)
+ {
+       const struct port_info *pi = netdev_priv(dev);
+       return pi->rss_size;
+ }
++#endif
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
+ static int get_rss_table(struct net_device *dev, u32 *p)
+ {
+       const struct port_info *pi = netdev_priv(dev);
+@@ -1903,6 +1992,7 @@ static int set_rss_table(struct net_device *dev, const u32 *p)
+               return write_rss(pi, pi->rss);
+       return 0;
+ }
++#endif
+ static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
+                    u32 *rules)
+@@ -1982,9 +2072,19 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
+       .set_eeprom        = set_eeprom,
+       .get_pauseparam    = get_pauseparam,
+       .set_pauseparam    = set_pauseparam,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++      .get_rx_csum       = get_rx_csum,
++      .set_rx_csum       = set_rx_csum,
++      .set_tx_csum       = ethtool_op_set_tx_ipv6_csum,
++      .set_sg            = ethtool_op_set_sg,
++#endif
+       .get_link          = ethtool_op_get_link,
+       .get_strings       = get_strings,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+       .set_phys_id       = identify_port,
++#else
++      .phys_id           = identify_port,
++#endif
+       .nway_reset        = restart_autoneg,
+       .get_sset_count    = get_sset_count,
+       .get_ethtool_stats = get_stats,
+@@ -1992,10 +2092,18 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
+       .get_regs          = get_regs,
+       .get_wol           = get_wol,
+       .set_wol           = set_wol,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++      .set_tso           = set_tso,
++      .set_flags         = set_flags,
++#endif
+       .get_rxnfc         = get_rxnfc,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+       .get_rxfh_indir_size = get_rss_table_size,
++#endif
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
+       .get_rxfh_indir    = get_rss_table,
+       .set_rxfh_indir    = set_rss_table,
++#endif
+       .flash_device      = set_flash,
+ };
+@@ -2902,6 +3010,7 @@ static int cxgb_close(struct net_device *dev)
+       return t4_enable_vi(adapter, adapter->fn, pi->viid, false, false);
+ }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
+ static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev,
+                                               struct rtnl_link_stats64 *ns)
+ {
+@@ -2943,6 +3052,49 @@ static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev,
+               ns->rx_length_errors + stats.rx_len_err + ns->rx_fifo_errors;
+       return ns;
+ }
++#else
++static struct net_device_stats *cxgb_get_stats(struct net_device *dev)
++{
++      struct port_stats stats;
++      struct port_info *p = netdev_priv(dev);
++      struct adapter *adapter = p->adapter;
++      struct net_device_stats *ns = &dev->stats;
++
++      spin_lock(&adapter->stats_lock);
++      t4_get_port_stats(adapter, p->tx_chan, &stats);
++      spin_unlock(&adapter->stats_lock);
++
++      ns->tx_bytes   = stats.tx_octets;
++      ns->tx_packets = stats.tx_frames;
++      ns->rx_bytes   = stats.rx_octets;
++      ns->rx_packets = stats.rx_frames;
++      ns->multicast  = stats.rx_mcast_frames;
++
++      /* detailed rx_errors */
++      ns->rx_length_errors = stats.rx_jabber + stats.rx_too_long +
++              stats.rx_runt;
++      ns->rx_over_errors   = 0;
++      ns->rx_crc_errors    = stats.rx_fcs_err;
++      ns->rx_frame_errors  = stats.rx_symbol_err;
++      ns->rx_fifo_errors   = stats.rx_ovflow0 + stats.rx_ovflow1 +
++              stats.rx_ovflow2 + stats.rx_ovflow3 +
++              stats.rx_trunc0 + stats.rx_trunc1 +
++              stats.rx_trunc2 + stats.rx_trunc3;
++      ns->rx_missed_errors = 0;
++
++      /* detailed tx_errors */
++      ns->tx_aborted_errors   = 0;
++      ns->tx_carrier_errors   = 0;
++      ns->tx_fifo_errors      = 0;
++      ns->tx_heartbeat_errors = 0;
++      ns->tx_window_errors    = 0;
++
++      ns->tx_errors = stats.tx_error_frames;
++      ns->rx_errors = stats.rx_symbol_err + stats.rx_fcs_err +
++              ns->rx_length_errors + stats.rx_len_err + ns->rx_fifo_errors;
++      return ns;
++}
++#endif
+ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+ {
+@@ -3043,10 +3195,16 @@ static const struct net_device_ops cxgb4_netdev_ops = {
+       .ndo_open             = cxgb_open,
+       .ndo_stop             = cxgb_close,
+       .ndo_start_xmit       = t4_eth_xmit,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
+       .ndo_get_stats64      = cxgb_get_stats,
++#else
++      .ndo_get_stats        = cxgb_get_stats,
++#endif
+       .ndo_set_rx_mode      = cxgb_set_rxmode,
+       .ndo_set_mac_address  = cxgb_set_mac_addr,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+       .ndo_set_features     = cxgb_set_features,
++#endif
+       .ndo_validate_addr    = eth_validate_addr,
+       .ndo_do_ioctl         = cxgb_ioctl,
+       .ndo_change_mtu       = cxgb_change_mtu,
+@@ -3650,7 +3808,11 @@ static int __devinit init_rss(struct adapter *adap)
+               if (!pi->rss)
+                       return -ENOMEM;
+               for (j = 0; j < pi->rss_size; j++)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+                       pi->rss[j] = ethtool_rxfh_indir_default(j, pi->nqsets);
++#else
++                      pi->rss[j] = j % pi->nqsets;
++#endif
+       }
+       return 0;
+ }
+@@ -3729,7 +3891,9 @@ static void free_some_resources(struct adapter *adapter)
+               t4_fw_bye(adapter, adapter->fn);
+ }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+ #define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
++#endif
+ #define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \
+                  NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
+@@ -3738,7 +3902,11 @@ static int __devinit init_one(struct pci_dev *pdev,
+ {
+       int func, i, err;
+       struct port_info *pi;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+       bool highdma = false;
++#else
++      unsigned int highdma = 0;
++#endif
+       struct adapter *adapter = NULL;
+       printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
+@@ -3764,7 +3932,11 @@ static int __devinit init_one(struct pci_dev *pdev,
+       }
+       if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+               highdma = true;
++#else
++              highdma = NETIF_F_HIGHDMA;
++#endif
+               err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+               if (err) {
+                       dev_err(&pdev->dev, "unable to obtain 64-bit DMA for "
+@@ -3834,19 +4006,35 @@ static int __devinit init_one(struct pci_dev *pdev,
+               pi = netdev_priv(netdev);
+               pi->adapter = adapter;
+               pi->xact_addr_filt = -1;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++              pi->rx_offload = RX_CSO;
++#endif
+               pi->port_id = i;
+               netdev->irq = pdev->irq;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+               netdev->hw_features = NETIF_F_SG | TSO_FLAGS |
+                       NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                       NETIF_F_RXCSUM | NETIF_F_RXHASH |
+                       NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+               if (highdma)
+                       netdev->hw_features |= NETIF_F_HIGHDMA;
+               netdev->features |= netdev->hw_features;
++#else
++              netdev->features |= netdev->hw_features | highdma;
++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) */
++#else
++              netdev->features |= NETIF_F_SG | TSO_FLAGS;
++              netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
++              netdev->features |= NETIF_F_GRO | NETIF_F_RXHASH | highdma;
++              netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
++#endif
+               netdev->vlan_features = netdev->features & VLAN_FEAT;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+               netdev->priv_flags |= IFF_UNICAST_FLT;
++#endif
+               netdev->netdev_ops = &cxgb4_netdev_ops;
+               SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
+diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
+index e111d97..e25544f 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
+@@ -216,8 +216,13 @@ static int map_skb(struct device *dev, const struct sk_buff *skb,
+       end = &si->frags[si->nr_frags];
+       for (fp = si->frags; fp < end; fp++) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+               *++addr = skb_frag_dma_map(dev, fp, 0, skb_frag_size(fp),
+                                          DMA_TO_DEVICE);
++#else
++              *++addr = dma_map_page(dev, fp->page, fp->page_offset,
++                                     skb_frag_size(fp), DMA_TO_DEVICE);
++#endif
+               if (dma_mapping_error(dev, *addr))
+                       goto unwind;
+       }
+@@ -1415,9 +1420,14 @@ int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb)
+ }
+ EXPORT_SYMBOL(cxgb4_ofld_send);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+ static inline void copy_frags(struct sk_buff *skb,
++#else
++static inline void copy_frags(struct skb_shared_info *ssi,
++#endif
+                             const struct pkt_gl *gl, unsigned int offset)
+ {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+       int i;
+       /* usually there's just one frag */
+@@ -1429,9 +1439,24 @@ static inline void copy_frags(struct sk_buff *skb,
+               __skb_fill_page_desc(skb, i, gl->frags[i].page,
+                                    gl->frags[i].offset,
+                                    gl->frags[i].size);
+-
+       /* get a reference to the last page, we don't own it */
+       get_page(gl->frags[gl->nfrags - 1].page);
++#else
++      unsigned int n;
++
++      /* usually there's just one frag */
++      ssi->frags[0].page = gl->frags[0].page;
++      ssi->frags[0].page_offset = gl->frags[0].page_offset + offset;
++      skb_frag_size_set(&ssi->frags[0],
++                        skb_frag_size(&gl->frags[0]) - offset);
++      ssi->nr_frags = gl->nfrags;
++      n = gl->nfrags - 1;
++      if (n)
++              memcpy(&ssi->frags[1], &gl->frags[1], n * sizeof(skb_frag_t));
++
++      /* get a reference to the last page, we don't own it */
++      get_page(gl->frags[n].page);
++#endif
+ }
+ /**
+@@ -1466,7 +1491,11 @@ struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
+               __skb_put(skb, pull_len);
+               skb_copy_to_linear_data(skb, gl->va, pull_len);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+               copy_frags(skb, gl, pull_len);
++#else
++              copy_frags(skb_shinfo(skb), gl, pull_len);
++#endif
+               skb->len = gl->tot_len;
+               skb->data_len = skb->len - pull_len;
+               skb->truesize += skb->data_len;
+@@ -1485,7 +1514,11 @@ EXPORT_SYMBOL(cxgb4_pktgl_to_skb);
+ static void t4_pktgl_free(const struct pkt_gl *gl)
+ {
+       int n;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+       const struct page_frag *p;
++#else
++      const skb_frag_t *p;
++#endif
+       for (p = gl->frags, n = gl->nfrags - 1; n--; p++)
+               put_page(p->page);
+@@ -1529,7 +1562,11 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
+               return;
+       }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+       copy_frags(skb, gl, RX_PKT_PAD);
++#else
++      copy_frags(skb_shinfo(skb), gl, RX_PKT_PAD);
++#endif
+       skb->len = gl->tot_len - RX_PKT_PAD;
+       skb->data_len = skb->len;
+       skb->truesize += skb->data_len;
+@@ -1564,6 +1601,9 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
+ {
+       bool csum_ok;
+       struct sk_buff *skb;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++      struct port_info *pi;
++#endif
+       const struct cpl_rx_pkt *pkt;
+       struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
+@@ -1591,9 +1631,16 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
+       if (skb->dev->features & NETIF_F_RXHASH)
+               skb->rxhash = (__force u32)pkt->rsshdr.hash_val;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++      pi = netdev_priv(skb->dev);
++#endif
+       rxq->stats.pkts++;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+       if (csum_ok && (q->netdev->features & NETIF_F_RXCSUM) &&
++#else
++      if (csum_ok && (pi->rx_offload & RX_CSO) &&
++#endif
+           (pkt->l2info & htonl(RXF_UDP | RXF_TCP))) {
+               if (!pkt->ip_frag) {
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+@@ -1705,7 +1752,11 @@ static int process_responses(struct sge_rspq *q, int budget)
+               rmb();
+               rsp_type = RSPD_TYPE(rc->type_gen);
+               if (likely(rsp_type == RSP_TYPE_FLBUF)) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+                       struct page_frag *fp;
++#else
++                      skb_frag_t *fp;
++#endif
+                       struct pkt_gl si;
+                       const struct rx_sw_desc *rsd;
+                       u32 len = ntohl(rc->pldbuflen_qid), bufsz, frags;
+@@ -1724,9 +1775,15 @@ static int process_responses(struct sge_rspq *q, int budget)
+                               rsd = &rxq->fl.sdesc[rxq->fl.cidx];
+                               bufsz = get_buf_size(rsd);
+                               fp->page = rsd->page;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+                               fp->offset = q->offset;
+                               fp->size = min(bufsz, len);
+                               len -= fp->size;
++#else
++                              fp->page_offset = q->offset;
++                              skb_frag_size_set(fp, min(bufsz, len));
++                              len -= skb_frag_size(fp);
++#endif
+                               if (!len)
+                                       break;
+                               unmap_rx_buf(q->adap, &rxq->fl);
+@@ -1738,16 +1795,29 @@ static int process_responses(struct sge_rspq *q, int budget)
+                        */
+                       dma_sync_single_for_cpu(q->adap->pdev_dev,
+                                               get_buf_addr(rsd),
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+                                               fp->size, DMA_FROM_DEVICE);
++#else
++                                              skb_frag_size(fp),
++                                              DMA_FROM_DEVICE);
++#endif
+                       si.va = page_address(si.frags[0].page) +
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+                               si.frags[0].offset;
++#else
++                              si.frags[0].page_offset;
++#endif
+                       prefetch(si.va);
+                       si.nfrags = frags + 1;
+                       ret = q->handler(q, q->cur_desc, &si);
+                       if (likely(ret == 0))
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+                               q->offset += ALIGN(fp->size, FL_ALIGN);
++#else
++                              q->offset += ALIGN(skb_frag_size(fp), FL_ALIGN);
++#endif
+                       else
+                               restore_rx_bufs(&si, &rxq->fl, frags);
+               } else if (likely(rsp_type == RSP_TYPE_CPL)) {
+-- 
+1.7.1
+