From: Selvin Xavier Date: Fri, 5 Dec 2014 18:31:50 +0000 (-0800) Subject: be2net backport patch X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=f8e0f107888c2ead99391c722b7dc8d02fbf1355;p=~emulex%2Ffor-vlad%2Fold%2Fcompat-rdma.git be2net backport patch Signed-off-by: Selvin Xavier --- diff --git a/patches/0021-be2net-backport-patch.patch b/patches/0021-be2net-backport-patch.patch new file mode 100644 index 0000000..110fcdb --- /dev/null +++ b/patches/0021-be2net-backport-patch.patch @@ -0,0 +1,1067 @@ +From dc3cc69f6acb3891404cd46300a2934511b605ef Mon Sep 17 00:00:00 2001 +From: Selvin Xavier +Date: Sat, 6 Dec 2014 15:16:41 +0530 +Subject: [PATCH 1/2] be2net: backport patch + +Signed-off-by: Selvin Xavier +--- + drivers/net/ethernet/emulex/benet/Makefile | 2 +- + drivers/net/ethernet/emulex/benet/be.h | 10 +- + drivers/net/ethernet/emulex/benet/be_cmds.c | 6 +- + drivers/net/ethernet/emulex/benet/be_compat.c | 74 +++++++ + drivers/net/ethernet/emulex/benet/be_compat.h | 126 +++++++++++ + drivers/net/ethernet/emulex/benet/be_ethtool.c | 43 +++- + drivers/net/ethernet/emulex/benet/be_main.c | 271 +++++++++++++++++++++--- + 7 files changed, 492 insertions(+), 40 deletions(-) + create mode 100644 drivers/net/ethernet/emulex/benet/be_compat.c + create mode 100644 drivers/net/ethernet/emulex/benet/be_compat.h + +diff --git a/drivers/net/ethernet/emulex/benet/Makefile b/drivers/net/ethernet/emulex/benet/Makefile +index 1a91b27..a32863b 100644 +--- a/drivers/net/ethernet/emulex/benet/Makefile ++++ b/drivers/net/ethernet/emulex/benet/Makefile +@@ -4,4 +4,4 @@ + + obj-$(CONFIG_BE2NET) += be2net.o + +-be2net-y := be_main.o be_cmds.o be_ethtool.o be_roce.o ++be2net-y := be_main.o be_cmds.o be_ethtool.o be_roce.o be_compat.o +diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h +index 9a2d752..fff6982 100644 +--- a/drivers/net/ethernet/emulex/benet/be.h ++++ b/drivers/net/ethernet/emulex/benet/be.h +@@ -20,6 +20,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -30,11 +31,13 @@ + #include + #include + #include ++#include + + #include "be_hw.h" + #include "be_roce.h" ++#include "be_compat.h" + +-#define DRV_VER "10.4u" ++#define DRV_VER "10.4u_ofed" + #define DRV_NAME "be2net" + #define BE_NAME "Emulex BladeEngine2" + #define BE3_NAME "Emulex BladeEngine3" +@@ -508,7 +511,9 @@ struct be_adapter { + u32 num_msix_roce_vec; + struct ocrdma_dev *ocrdma_dev; + struct list_head entry; +- ++#ifndef HAVE_NDO_GET_STATS64 ++ struct net_device_stats net_stats; ++#endif + u32 flash_status; + struct completion et_cmd_compl; + +@@ -532,6 +537,7 @@ struct be_adapter { + int be_get_temp_freq; + u8 pf_number; + struct rss_info rss_info; ++ struct vlan_group *vlan_grp; + }; + + #define be_physfn(adapter) (!adapter->virtfn) +diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c +index fead5c6..1d12f49 100644 +--- a/drivers/net/ethernet/emulex/benet/be_cmds.c ++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c +@@ -1920,7 +1920,11 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value) + req->if_flags = + cpu_to_le32(BE_IF_FLAGS_VLAN_PROMISCUOUS); + } else { ++#ifdef HAVE_NETDEV_HW_ADDR + struct netdev_hw_addr *ha; ++#else ++ struct dev_addr_list *ha; ++#endif + int i = 0; + + req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_MULTICAST); +@@ -1934,7 +1938,7 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value) + be_if_cap_flags(adapter)); + req->mcast_num = cpu_to_le32(netdev_mc_count(adapter->netdev)); + netdev_for_each_mc_addr(ha, adapter->netdev) +- memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN); ++ memcpy(req->mcast_mac[i++].byte, ha->DMI_ADDR, ETH_ALEN); + } + + if ((req->if_flags_mask & cpu_to_le32(be_if_cap_flags(adapter))) != +diff --git a/drivers/net/ethernet/emulex/benet/be_compat.c b/drivers/net/ethernet/emulex/benet/be_compat.c +new file mode 100644 +index 0000000..d1563d3 +--- /dev/null ++++ b/drivers/net/ethernet/emulex/benet/be_compat.c +@@ -0,0 +1,74 @@ ++#include "be.h" ++ ++#if defined(CONFIG_PCI_IOV) ++#define sriov_kernel true ++#else ++#define sriov_kernel false ++#endif ++ ++#ifndef PCI_DEV_FLAGS_ASSIGNED ++#define PCI_DEV_FLAGS_ASSIGNED 0x04 ++#endif ++ ++#ifdef CONFIG_PCI_IOV ++int be_find_vfs(struct pci_dev *pdev, int vf_state) ++{ ++ struct pci_dev *dev = pdev; ++ int vfs = 0, assigned_vfs = 0, pos; ++ ++ if (!sriov_kernel) ++ return 0; ++ ++ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); ++ if (!pos) ++ return 0; ++ ++ dev = pci_get_device(pdev->vendor, PCI_ANY_ID, NULL); ++ while (dev) { ++ if (dev->is_virtfn && pci_physfn(dev) == pdev) { ++ vfs++; ++ if (dev->dev_flags & PCI_DEV_FLAGS_ASSIGNED) ++ assigned_vfs++; ++ } ++ dev = pci_get_device(pdev->vendor, PCI_ANY_ID, dev); ++ } ++ return (vf_state == ASSIGNED) ? assigned_vfs : vfs; ++} ++ ++#ifndef HAVE_PCI_VF_ASSIGNED ++/** ++ * pci_vfs_assigned - returns number of VFs are assigned to a guest ++ * @dev: the PCI device ++ * ++ * Returns number of VFs belonging to this device that are assigned to a guest. ++ * If device is not a physical function returns -ENODEV. ++ */ ++int pci_vfs_assigned(struct pci_dev *pdev) ++{ ++ return be_find_vfs(pdev, ASSIGNED); ++} ++ ++/** ++ * pci_num_vf - return number of VFs associated with a PF device_release_driver ++ * @dev: the PCI device ++ * ++ * Returns number of VFs, or 0 if SR-IOV is not enabled. ++ */ ++int pci_num_vf(struct pci_dev *pdev) ++{ ++ return be_find_vfs(pdev, ENABLED); ++} ++ ++int pci_sriov_get_totalvfs(struct pci_dev *pdev) ++{ ++ u16 num = 0; ++ int pos; ++ ++ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); ++ if (pos) ++ pci_read_config_word(pdev, pos + PCI_SRIOV_TOTAL_VF, &num); ++ return num; ++} ++ ++#endif ++#endif /* CONFIG_PCI_IOV */ +diff --git a/drivers/net/ethernet/emulex/benet/be_compat.h b/drivers/net/ethernet/emulex/benet/be_compat.h +new file mode 100644 +index 0000000..e6a94f7 +--- /dev/null ++++ b/drivers/net/ethernet/emulex/benet/be_compat.h +@@ -0,0 +1,126 @@ ++#ifndef BE_COMPAT_H ++#define BE_COMPAT_H ++ ++#include ++ ++#ifndef VLAN_N_VID ++#define VLAN_N_VID 4096 ++#endif ++ ++#ifndef HAVE_VLAN_HWACCEL_RECEIVE_SKB ++#define USE_NEW_VLAN_MODEL ++#endif ++ ++#if defined(USE_NEW_VLAN_MODEL) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) ++/* vlan_gro_frags() can be safely called when vlan_group is NULL ++ * * for kernels >= 3.0 or when kernels uses USE_NEW_VLAN_MODEL. ++ */ ++#define NULL_VLAN_GRP_SAFE ++#endif ++ ++static inline struct sk_buff *__vlan_put_tag_fixed(struct sk_buff *skb, ++ __be16 vlan_proto, ++ ushort vlan_tag) ++{ ++#ifdef HAVE_3_PARAMS_FOR_VLAN_PUT_TAG ++ struct sk_buff *new_skb = __vlan_put_tag(skb, vlan_proto, vlan_tag); ++#else ++ struct sk_buff *new_skb = __vlan_put_tag(skb, vlan_tag); ++#endif ++ return new_skb; ++} ++ ++#ifdef USE_NEW_VLAN_MODEL ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) ++struct vlan_group { ++ char dummy; ++}; ++#endif ++ ++static inline int vlan_hwaccel_receive_skb_compat(struct sk_buff *skb, ++ struct vlan_group *grp, ++ u16 vlan_tci) ++{ ++#ifdef HAVE_3_PARAMS_FOR_VLAN_HWACCEL_PUT_TAG ++ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci); ++#else ++ __vlan_hwaccel_put_tag(skb, vlan_tci); ++#endif ++ return netif_receive_skb(skb); ++} ++ ++static inline gro_result_t vlan_gro_frags_compat(struct napi_struct *napi, ++ struct vlan_group *grp, ++ unsigned int vlan_tci) ++{ ++#ifdef HAVE_3_PARAMS_FOR_VLAN_HWACCEL_PUT_TAG ++ __vlan_hwaccel_put_tag(napi->skb, htons(ETH_P_8021Q), vlan_tci); ++#else ++ __vlan_hwaccel_put_tag(napi->skb, vlan_tci); ++#endif ++ return napi_gro_frags(napi); ++} ++ ++#define vlan_hwaccel_receive_skb vlan_hwaccel_receive_skb_compat ++#define vlan_gro_frags vlan_gro_frags_compat ++#endif ++ ++#ifdef CONFIG_PCI_IOV ++int be_find_vfs(struct pci_dev *pdev, int vf_state); ++#ifndef HAVE_PCI_VF_ASSIGNED ++int pci_vfs_assigned(struct pci_dev *pdev); ++int pci_num_vf(struct pci_dev *pdev); ++int pci_sriov_get_totalvfs(struct pci_dev *pdev); ++#endif ++#else ++#define pci_vfs_assigned(x) 0 ++#define pci_num_vf(x) 0 ++#endif /* CONFIG_PCI_IOV */ ++ ++#ifndef NETIF_F_HW_VLAN_CTAG_TX ++#define NETIF_F_HW_VLAN_CTAG_TX NETIF_F_HW_VLAN_TX ++#endif ++#ifndef NETIF_F_HW_VLAN_CTAG_RX ++#define NETIF_F_HW_VLAN_CTAG_RX NETIF_F_HW_VLAN_RX ++#endif ++#ifndef NETIF_F_HW_VLAN_CTAG_FILTER ++#define NETIF_F_HW_VLAN_CTAG_FILTER NETIF_F_HW_VLAN_FILTER ++#endif ++ ++#ifndef HAVE_NETDEV_HW_FEATURES ++#define hw_features features ++#endif ++ ++#ifndef netdev_for_each_mc_addr ++#define netdev_for_each_mc_addr(h, n) for (h = (n)->mc_list; h; h = h->next) ++#endif ++ ++/* When new mc-list macros were used in 2.6.35, dev_mc_list was dropped */ ++#ifdef HAVE_NETDEV_HW_ADDR ++#define DMI_ADDR addr ++#else ++#define DMI_ADDR dmi_addr ++#endif /* dev_mc_list */ ++ ++#ifndef DUPLEX_UNKNOWN ++#define DUPLEX_UNKNOWN 0xFF ++#endif ++ ++#ifndef HAVE_ETHER_ADDR_COPY ++static inline void ether_addr_copy(u8 *dst, const u8 *src) ++{ ++#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ++ *(u32 *)dst = *(const u32 *)src; ++ *(u16 *)(dst + 4) = *(const u16 *)(src + 4); ++#else ++ u16 *a = (u16 *)dst; ++ const u16 *b = (const u16 *)src; ++ ++ a[0] = b[0]; ++ a[1] = b[1]; ++ a[2] = b[2]; ++#endif ++} ++#endif ++ ++#endif /* BE_COMPAT_H */ +diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c +index e42a791..04628fa 100644 +--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c ++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c +@@ -380,7 +380,11 @@ static void be_get_ethtool_stats(struct net_device *netdev, + struct be_rx_obj *rxo; + struct be_tx_obj *txo; + void *p; +- unsigned int i, j, base = 0, start; ++ unsigned int i, j, base = 0; ++ bool ret = false; ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ unsigned int start; ++#endif + + for (i = 0; i < ETHTOOL_STATS_NUM; i++) { + p = (u8 *)&adapter->drv_stats + et_stats[i].offset; +@@ -392,10 +396,15 @@ static void be_get_ethtool_stats(struct net_device *netdev, + struct be_rx_stats *stats = rx_stats(rxo); + + do { ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ + start = u64_stats_fetch_begin_irq(&stats->sync); ++#endif + data[base] = stats->rx_bytes; + data[base + 1] = stats->rx_pkts; +- } while (u64_stats_fetch_retry_irq(&stats->sync, start)); ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ ret = u64_stats_fetch_retry_irq(&stats->sync, start); ++#endif ++ } while (ret); + + for (i = 2; i < ETHTOOL_RXSTATS_NUM; i++) { + p = (u8 *)stats + et_rx_stats[i].offset; +@@ -408,19 +417,31 @@ static void be_get_ethtool_stats(struct net_device *netdev, + struct be_tx_stats *stats = tx_stats(txo); + + do { ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ ret = false; + start = u64_stats_fetch_begin_irq(&stats->sync_compl); ++#endif + data[base] = stats->tx_compl; +- } while (u64_stats_fetch_retry_irq(&stats->sync_compl, start)); ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ ret = u64_stats_fetch_retry_irq(&stats->sync_compl, start); ++#endif ++ } while (ret); + + do { ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ ret = false; + start = u64_stats_fetch_begin_irq(&stats->sync); ++#endif + for (i = 1; i < ETHTOOL_TXSTATS_NUM; i++) { + p = (u8 *)stats + et_tx_stats[i].offset; + data[base + i] = + (et_tx_stats[i].size == sizeof(u64)) ? + *(u64 *)p : *(u32 *)p; + } +- } while (u64_stats_fetch_retry_irq(&stats->sync, start)); ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ ret = u64_stats_fetch_retry_irq(&stats->sync, start); ++#endif ++ } while (ret); + base += ETHTOOL_TXSTATS_NUM; + } + } +@@ -698,7 +719,6 @@ be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) + be_cmd_get_flow_control(adapter, &ecmd->tx_pause, &ecmd->rx_pause); + ecmd->autoneg = adapter->phy.fc_autoneg; + } +- + static int + be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) + { +@@ -718,6 +738,7 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) + return be_cmd_status(status); + } + ++#ifdef HAVE_SET_PHYS_ID + static int be_set_phys_id(struct net_device *netdev, + enum ethtool_phys_id_state state) + { +@@ -746,6 +767,7 @@ static int be_set_phys_id(struct net_device *netdev, + + return 0; + } ++#endif + + static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump) + { +@@ -1136,6 +1158,7 @@ static int be_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd) + return status; + } + ++#ifdef HAVE_GET_SET_CHANNELS + static void be_get_channels(struct net_device *netdev, + struct ethtool_channels *ch) + { +@@ -1160,7 +1183,9 @@ static int be_set_channels(struct net_device *netdev, + status = be_update_queues(adapter); + return be_cmd_status(status); + } ++#endif + ++#ifdef HAVE_GET_SET_RXFH + static u32 be_get_rxfh_indir_size(struct net_device *netdev) + { + return RSS_INDIR_TABLE_LEN; +@@ -1225,6 +1250,8 @@ static int be_set_rxfh(struct net_device *netdev, const u32 *indir, + return 0; + } + ++#endif ++ + static int be_get_module_info(struct net_device *netdev, + struct ethtool_modinfo *modinfo) + { +@@ -1291,7 +1318,9 @@ const struct ethtool_ops be_ethtool_ops = { + .get_pauseparam = be_get_pauseparam, + .set_pauseparam = be_set_pauseparam, + .get_strings = be_get_stat_strings, ++#ifdef HAVE_SET_PHYS_ID + .set_phys_id = be_set_phys_id, ++#endif + .set_dump = be_set_dump, + .get_msglevel = be_get_msg_level, + .set_msglevel = be_set_msg_level, +@@ -1303,12 +1332,16 @@ const struct ethtool_ops be_ethtool_ops = { + .self_test = be_self_test, + .get_rxnfc = be_get_rxnfc, + .set_rxnfc = be_set_rxnfc, ++#ifdef HAVE_GET_SET_RXFH + .get_rxfh_indir_size = be_get_rxfh_indir_size, + .get_rxfh_key_size = be_get_rxfh_key_size, + .get_rxfh = be_get_rxfh, + .set_rxfh = be_set_rxfh, ++#endif ++#ifdef HAVE_GET_SET_CHANNELS + .get_channels = be_get_channels, + .set_channels = be_set_channels, ++#endif + .get_module_info = be_get_module_info, + .get_module_eeprom = be_get_module_eeprom + }; +diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c +index 3e8475c..916c4a3 100644 +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -143,8 +143,8 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q, + q->len = len; + q->entry_size = entry_size; + mem->size = len * entry_size; +- mem->va = dma_zalloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma, +- GFP_KERNEL); ++ mem->va = dma_alloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma, ++ GFP_KERNEL|__GFP_ZERO); + if (!mem->va) + return -ENOMEM; + return 0; +@@ -579,6 +579,76 @@ void be_parse_stats(struct be_adapter *adapter) + } + } + ++#ifndef HAVE_NDO_GET_STATS64 ++static void be_get_error_stats(struct be_adapter *adapter, ++ struct net_device_stats *stats) ++{ ++ struct be_drv_stats *drvs = &adapter->drv_stats; ++ ++ /* bad pkts received */ ++ stats->rx_errors = drvs->rx_crc_errors + ++ drvs->rx_alignment_symbol_errors + ++ drvs->rx_in_range_errors + ++ drvs->rx_out_range_errors + ++ drvs->rx_frame_too_long + ++ drvs->rx_dropped_too_small + ++ drvs->rx_dropped_too_short + ++ drvs->rx_dropped_header_too_small + ++ drvs->rx_dropped_tcp_length + ++ drvs->rx_dropped_runt; ++ ++ /* detailed rx errors */ ++ stats->rx_length_errors = drvs->rx_in_range_errors + ++ drvs->rx_out_range_errors + ++ drvs->rx_frame_too_long; ++ ++ stats->rx_crc_errors = drvs->rx_crc_errors; ++ ++ /* frame alignment errors */ ++ stats->rx_frame_errors = drvs->rx_alignment_symbol_errors; ++ ++ /* receiver fifo overrun */ ++ /* drops_no_pbuf is no per i/f, it's per BE card */ ++ stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop + ++ drvs->rx_input_fifo_overflow_drop + ++ drvs->rx_drops_no_pbuf; ++} ++ ++static struct net_device_stats *be_get_stats(struct net_device *dev) ++{ ++ struct be_adapter *adapter = netdev_priv(dev); ++ struct net_device_stats *stats = &adapter->net_stats; ++ struct be_rx_obj *rxo; ++ struct be_tx_obj *txo; ++ unsigned long pkts = 0, bytes = 0, mcast = 0, drops = 0; ++ int i; ++ ++ for_all_rx_queues(adapter, rxo, i) { ++ pkts += rx_stats(rxo)->rx_pkts; ++ bytes += rx_stats(rxo)->rx_bytes; ++ mcast += rx_stats(rxo)->rx_mcast_pkts; ++ drops += rx_stats(rxo)->rx_drops_no_skbs + ++ rx_stats(rxo)->rx_drops_no_frags; ++ } ++ stats->rx_packets = pkts; ++ stats->rx_bytes = bytes; ++ stats->multicast = mcast; ++ stats->rx_dropped = drops; ++ ++ pkts = 0; ++ bytes = 0; ++ for_all_tx_queues(adapter, txo, i) { ++ pkts += tx_stats(txo)->tx_pkts; ++ bytes += tx_stats(txo)->tx_bytes; ++ } ++ stats->tx_packets = pkts; ++ stats->tx_bytes = bytes; ++ ++ be_get_error_stats(adapter, stats); ++ ++ return stats; ++} ++#else + static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) + { +@@ -587,17 +657,25 @@ static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, + struct be_rx_obj *rxo; + struct be_tx_obj *txo; + u64 pkts, bytes; ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ + unsigned int start; ++ bool ret = false; ++#endif + int i; + + for_all_rx_queues(adapter, rxo, i) { ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ + const struct be_rx_stats *rx_stats = rx_stats(rxo); + + do { + start = u64_stats_fetch_begin_irq(&rx_stats->sync); ++#endif + pkts = rx_stats(rxo)->rx_pkts; + bytes = rx_stats(rxo)->rx_bytes; +- } while (u64_stats_fetch_retry_irq(&rx_stats->sync, start)); ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ ret = u64_stats_fetch_retry_irq(&rx_stats->sync, start) ++ } while (ret); ++#endif + stats->rx_packets += pkts; + stats->rx_bytes += bytes; + stats->multicast += rx_stats(rxo)->rx_mcast_pkts; +@@ -606,13 +684,19 @@ static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, + } + + for_all_tx_queues(adapter, txo, i) { ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ + const struct be_tx_stats *tx_stats = tx_stats(txo); + + do { ++ ret = false; + start = u64_stats_fetch_begin_irq(&tx_stats->sync); ++#endif + pkts = tx_stats(txo)->tx_pkts; + bytes = tx_stats(txo)->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->sync, start)); ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ ret = u64_stats_fetch_retry_irq(&tx_stats->sync, start); ++ } while (ret); ++#endif + stats->tx_packets += pkts; + stats->tx_bytes += bytes; + } +@@ -646,6 +730,7 @@ static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, + drvs->rx_drops_no_pbuf; + return stats; + } ++#endif + + void be_link_status_update(struct be_adapter *adapter, u8 link_status) + { +@@ -887,7 +972,7 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, + } + + if (vlan_tag) { +- skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); ++ skb = __vlan_put_tag_fixed(skb, htons(ETH_P_8021Q), vlan_tag); + if (unlikely(!skb)) + return skb; + skb->vlan_tci = 0; +@@ -896,7 +981,7 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, + /* Insert the outer VLAN, if any */ + if (adapter->qnq_vid) { + vlan_tag = adapter->qnq_vid; +- skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); ++ skb = __vlan_put_tag_fixed(skb, htons(ETH_P_8021Q), vlan_tag); + if (unlikely(!skb)) + return skb; + if (skip_hw_vlan) +@@ -1152,17 +1237,29 @@ set_vlan_promisc: + return status; + } + ++#ifdef HAVE_NDO_RX_ADD_VID_HAS_3_PARAMS + static int be_vlan_add_vid(struct net_device *netdev, __be16 proto, u16 vid) ++#else ++static void be_vlan_add_vid(struct net_device *netdev, u16 vid) ++#endif + { + struct be_adapter *adapter = netdev_priv(netdev); + int status = 0; + + /* Packets with VID 0 are always received by Lancer by default */ + if (lancer_chip(adapter) && vid == 0) ++#ifdef HAVE_NDO_RX_ADD_VID_HAS_3_PARAMS + return status; ++#else ++ return; ++#endif + + if (test_bit(vid, adapter->vids)) ++#ifdef HAVE_NDO_RX_ADD_VID_HAS_3_PARAMS + return status; ++#else ++ return; ++#endif + + set_bit(vid, adapter->vids); + adapter->vlans_added++; +@@ -1173,21 +1270,39 @@ static int be_vlan_add_vid(struct net_device *netdev, __be16 proto, u16 vid) + clear_bit(vid, adapter->vids); + } + +- return status; ++#ifdef HAVE_NDO_RX_ADD_VID_HAS_3_PARAMS ++ return status; ++#else ++ return; ++#endif + } + ++#ifdef HAVE_NDO_RX_ADD_VID_HAS_3_PARAMS + static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid) ++#else ++static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) ++#endif + { ++ int status = 0; + struct be_adapter *adapter = netdev_priv(netdev); + + /* Packets with VID 0 are always received by Lancer by default */ + if (lancer_chip(adapter) && vid == 0) ++#ifdef HAVE_NDO_RX_ADD_VID_HAS_3_PARAMS + return 0; +- ++#else ++ return; ++#endif + clear_bit(vid, adapter->vids); + adapter->vlans_added--; + +- return be_vid_config(adapter); ++ status = be_vid_config(adapter); ++ ++#ifdef HAVE_NDO_RX_ADD_VID_HAS_3_PARAMS ++ return status; ++#else ++ return; ++#endif + } + + static void be_clear_promisc(struct be_adapter *adapter) +@@ -1318,8 +1433,10 @@ static int be_get_vf_config(struct net_device *netdev, int vf, + return -EINVAL; + + vi->vf = vf; ++#ifdef HAVE_TX_RATE_LIMI + vi->max_tx_rate = vf_cfg->tx_rate; + vi->min_tx_rate = 0; ++#endif + vi->vlan = vf_cfg->vlan_tag & VLAN_VID_MASK; + vi->qos = vf_cfg->vlan_tag >> VLAN_PRIO_SHIFT; + memcpy(&vi->mac, vf_cfg->mac_addr, ETH_ALEN); +@@ -1363,6 +1480,7 @@ static int be_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) + return 0; + } + ++#ifdef HAVE_SET_VF_RATE + static int be_set_vf_tx_rate(struct net_device *netdev, int vf, + int min_tx_rate, int max_tx_rate) + { +@@ -1425,6 +1543,8 @@ err: + return be_cmd_status(status); + } + ++#endif ++ + static int be_set_vf_link_state(struct net_device *netdev, int vf, + int link_state) + { +@@ -1460,7 +1580,7 @@ static void be_aic_update(struct be_aic_obj *aic, u64 rx_pkts, u64 tx_pkts, + static void be_eqd_update(struct be_adapter *adapter) + { + struct be_set_eqd set_eqd[MAX_EVT_QS]; +- int eqd, i, num = 0, start; ++ int eqd, i, num = 0; + struct be_aic_obj *aic; + struct be_eq_obj *eqo; + struct be_rx_obj *rxo; +@@ -1468,6 +1588,10 @@ static void be_eqd_update(struct be_adapter *adapter) + u64 rx_pkts, tx_pkts; + ulong now; + u32 pps, delta; ++ bool ret = false; ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ int start; ++#endif + + for_all_evt_queues(adapter, eqo, i) { + aic = &adapter->aic_obj[eqo->idx]; +@@ -1480,15 +1604,26 @@ static void be_eqd_update(struct be_adapter *adapter) + + rxo = &adapter->rx_obj[eqo->idx]; + do { ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ + start = u64_stats_fetch_begin_irq(&rxo->stats.sync); ++#endif + rx_pkts = rxo->stats.rx_pkts; +- } while (u64_stats_fetch_retry_irq(&rxo->stats.sync, start)); ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ ret = u64_stats_fetch_retry_irq(&rxo->stats.sync, start); ++#endif ++ } while (ret); + + txo = &adapter->tx_obj[eqo->idx]; + do { ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ ret = false; + start = u64_stats_fetch_begin_irq(&txo->stats.sync); ++#endif + tx_pkts = txo->stats.tx_reqs; +- } while (u64_stats_fetch_retry_irq(&txo->stats.sync, start)); ++#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ ++ ret = u64_stats_fetch_retry_irq(&txo->stats.sync, start); ++#endif ++ } while (ret); + + /* Skip, if wrapped around or first calculation */ + now = jiffies; +@@ -1685,18 +1820,28 @@ static void be_rx_compl_process(struct be_rx_obj *rxo, struct napi_struct *napi, + else + skb_checksum_none_assert(skb); + ++#ifndef NULL_VLAN_GRP_SAFE ++ if (rxcp->vlanf && !adapter->vlan_grp) { ++ __vlan_put_tag(skb, rxcp->vlan_tag); ++ rxcp->vlanf = 0; ++ } ++#endif + skb->protocol = eth_type_trans(skb, netdev); + skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]); + if (netdev->features & NETIF_F_RXHASH) + skb_set_hash(skb, rxcp->rss_hash, PKT_HASH_TYPE_L3); + ++#ifdef HAVE_SK_BUFF_CSUM_LEVEL + skb->csum_level = rxcp->tunneled; ++#else ++ skb->encapsulation = rxcp->tunneled; ++#endif + skb_mark_napi_id(skb, napi); + + if (rxcp->vlanf) +- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rxcp->vlan_tag); +- +- netif_receive_skb(skb); ++ vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, rxcp->vlan_tag); ++ else ++ netif_receive_skb(skb); + } + + /* Process the RX completion indicated by rxcp when GRO is enabled */ +@@ -1748,13 +1893,19 @@ static void be_rx_compl_process_gro(struct be_rx_obj *rxo, + if (adapter->netdev->features & NETIF_F_RXHASH) + skb_set_hash(skb, rxcp->rss_hash, PKT_HASH_TYPE_L3); + ++#ifdef HAVE_SK_BUFF_CSUM_LEVEL + skb->csum_level = rxcp->tunneled; ++#else ++ skb->encapsulation = rxcp->tunneled; ++#endif ++ + skb_mark_napi_id(skb, napi); + + if (rxcp->vlanf) +- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rxcp->vlan_tag); + +- napi_gro_frags(napi); ++ vlan_gro_frags(napi, adapter->vlan_grp, rxcp->vlan_tag); ++ else ++ napi_gro_frags(napi); + } + + static void be_parse_rx_compl_v1(struct be_eth_rx_compl *compl, +@@ -1983,7 +2134,11 @@ static u16 be_tx_compl_process(struct be_adapter *adapter, + queue_tail_inc(txq); + } while (cur_index != last_index); + ++#ifdef HAVE_DEV_CONSUME_SKB_ANY + dev_consume_skb_any(sent_skb); ++#else ++ dev_kfree_skb_any(sent_skb); ++#endif + return num_wrbs; + } + +@@ -2253,9 +2408,10 @@ static int be_tx_qs_create(struct be_adapter *adapter) + sizeof(struct be_eth_tx_compl)); + if (status) + return status; +- ++#ifdef HAVE_U64_STATS_SYNC + u64_stats_init(&txo->stats.sync); + u64_stats_init(&txo->stats.sync_compl); ++#endif + + /* If num_evt_qs is less than num_tx_qs, then more than + * one txq share an eq +@@ -2318,7 +2474,9 @@ static int be_rx_cqs_create(struct be_adapter *adapter) + if (rc) + return rc; + ++#ifdef HAVE_U64_STATS_SYNC + u64_stats_init(&rxo->stats.sync); ++#endif + eq = &adapter->eq_obj[i % adapter->num_evt_qs].q; + rc = be_cmd_cq_create(adapter, cq, eq, false, 3); + if (rc) +@@ -2372,9 +2530,16 @@ static irqreturn_t be_msix(int irq, void *dev) + return IRQ_HANDLED; + } + +-static inline bool do_gro(struct be_rx_compl_info *rxcp) ++static inline bool do_gro(struct be_adapter *adapter, ++ struct be_rx_compl_info *rxcp) + { +- return (rxcp->tcpf && !rxcp->err && rxcp->l4_csum) ? true : false; ++ bool insert_tag = false; ++ ++#ifndef NULL_VLAN_GRP_SAFE ++ insert_tag = rxcp->vlanf && !adapter->vlan_grp; ++#endif ++ return rxcp->tcpf && !rxcp->err && ++ rxcp->l4_csum && !insert_tag; + } + + static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi, +@@ -2411,7 +2576,7 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi, + } + + /* Don't do gro when we're busy_polling */ +- if (do_gro(rxcp) && polling != BUSY_POLLING) ++ if (do_gro(adapter, rxcp) && polling != BUSY_POLLING) + be_rx_compl_process_gro(rxo, napi, rxcp); + else + be_rx_compl_process(rxo, napi, rxcp); +@@ -2664,6 +2829,9 @@ static int be_msix_enable(struct be_adapter *adapter) + { + int i, num_vec; + struct device *dev = &adapter->pdev->dev; ++#ifndef HAVE_PCI_ENABLE_MSIX_RANGE ++ int status; ++#endif + + /* If RoCE is supported, program the max number of NIC vectors that + * may be configured via set-channels, along with vectors needed for +@@ -2678,11 +2846,29 @@ static int be_msix_enable(struct be_adapter *adapter) + for (i = 0; i < num_vec; i++) + adapter->msix_entries[i].entry = i; + ++#ifdef HAVE_PCI_ENABLE_MSIX_RANGE + num_vec = pci_enable_msix_range(adapter->pdev, adapter->msix_entries, + MIN_MSIX_VECTORS, num_vec); + if (num_vec < 0) + goto fail; ++#else ++ status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec); ++ if (status == 0) { ++ goto done; ++ } else if (status >= MIN_MSIX_VECTORS) { ++ dev_info(dev, "Could not get %d MSI-x vector(s)\n", num_vec); ++ dev_info(dev, "Using %d vector(s)\n", status); ++ num_vec = status; ++ status = pci_enable_msix(adapter->pdev, adapter->msix_entries, ++ num_vec); ++ if (status) ++ goto fail; ++ } else { ++ goto fail; ++ } ++#endif + ++done: + if (be_roce_supported(adapter) && num_vec > MIN_MSIX_VECTORS) { + adapter->num_msix_roce_vec = num_vec / 2; + dev_info(dev, "enabled %d MSI-x vector(s) for RoCE\n", +@@ -2700,7 +2886,7 @@ fail: + + /* INTx is not supported in VFs, so fail probe if enable_msix fails */ + if (!be_physfn(adapter)) +- return num_vec; ++ return status; + return 0; + } + +@@ -2977,7 +3163,7 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) + + cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config); + cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, +- GFP_KERNEL); ++ GFP_KERNEL | __GFP_ZERO); + if (!cmd.va) + return -ENOMEM; + +@@ -3585,7 +3771,11 @@ static int be_setup_queues(struct be_adapter *adapter) + if (status) + goto err; + ++#if HAVE_RETURN_INT_FOR_SET_NUM_TX_QUEUES + status = netif_set_real_num_tx_queues(netdev, adapter->num_tx_qs); ++#else ++ netif_set_real_num_tx_queues(netdev, adapter->num_tx_qs); ++#endif + if (status) + goto err; + +@@ -4297,6 +4487,16 @@ fw_exit: + return status; + } + ++#ifndef USE_NEW_VLAN_MODEL ++static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp) ++{ ++ struct be_adapter *adapter = netdev_priv(netdev); ++ ++ adapter->vlan_grp = grp; ++} ++#endif ++ ++#ifdef HAVE_NDO_BRIDGE_SET_GET_LINK + static int be_ndo_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh) + { + struct be_adapter *adapter = netdev_priv(dev); +@@ -4363,6 +4563,8 @@ static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, + BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB); + } + ++#endif ++ + #ifdef CONFIG_BE2NET_VXLAN + static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family, + __be16 port) +@@ -4421,11 +4623,6 @@ static void be_del_vxlan_port(struct net_device *netdev, sa_family_t sa_family, + "Disabled VxLAN offloads for UDP port %d\n", + be16_to_cpu(port)); + } +- +-static bool be_gso_check(struct sk_buff *skb, struct net_device *dev) +-{ +- return vxlan_gso_check(skb); +-} + #endif + + static const struct net_device_ops be_netdev_ops = { +@@ -4435,27 +4632,37 @@ static const struct net_device_ops be_netdev_ops = { + .ndo_set_rx_mode = be_set_rx_mode, + .ndo_set_mac_address = be_mac_addr_set, + .ndo_change_mtu = be_change_mtu, ++#ifndef HAVE_NDO_GET_STATS64 ++ .ndo_get_stats = be_get_stats, ++#else + .ndo_get_stats64 = be_get_stats64, ++#endif + .ndo_validate_addr = eth_validate_addr, ++#ifndef USE_NEW_VLAN_MODEL ++ .ndo_vlan_rx_register = be_vlan_register, ++#endif + .ndo_vlan_rx_add_vid = be_vlan_add_vid, + .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, + .ndo_set_vf_mac = be_set_vf_mac, + .ndo_set_vf_vlan = be_set_vf_vlan, ++#ifdef HAVE_SET_VF_RATE + .ndo_set_vf_rate = be_set_vf_tx_rate, ++#endif + .ndo_get_vf_config = be_get_vf_config, + .ndo_set_vf_link_state = be_set_vf_link_state, + #ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = be_netpoll, + #endif ++#ifdef HAVE_NDO_BRIDGE_SET_GET_LINK + .ndo_bridge_setlink = be_ndo_bridge_setlink, + .ndo_bridge_getlink = be_ndo_bridge_getlink, ++#endif + #ifdef CONFIG_NET_RX_BUSY_POLL + .ndo_busy_poll = be_busy_poll, + #endif + #ifdef CONFIG_BE2NET_VXLAN + .ndo_add_vxlan_port = be_add_vxlan_port, + .ndo_del_vxlan_port = be_del_vxlan_port, +- .ndo_gso_check = be_gso_check, + #endif + }; + +@@ -4481,7 +4688,9 @@ static void be_netdev_init(struct net_device *netdev) + netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + ++#ifdef HAVE_NET_DEVICE_PRIV_FLAGS + netdev->priv_flags |= IFF_UNICAST_FLT; ++#endif + + netdev->flags |= IFF_MULTICAST; + +@@ -4594,7 +4803,7 @@ static int be_ctrl_init(struct be_adapter *adapter) + rx_filter->size = sizeof(struct be_cmd_req_rx_filter); + rx_filter->va = dma_zalloc_coherent(&adapter->pdev->dev, + rx_filter->size, &rx_filter->dma, +- GFP_KERNEL); ++ GFP_KERNEL | __GFP_ZERO); + if (!rx_filter->va) { + status = -ENOMEM; + goto free_mbox; +@@ -4643,7 +4852,7 @@ static int be_stats_init(struct be_adapter *adapter) + cmd->size = sizeof(struct be_cmd_req_get_stats_v2); + + cmd->va = dma_zalloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma, +- GFP_KERNEL); ++ GFP_KERNEL | __GFP_ZERO); + if (!cmd->va) + return -ENOMEM; + return 0; +-- +1.7.9.5 +