Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbf13895 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "atlantic forwarding driver v1.0.27"

parents a6b1c460 2b745f40
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ if AQFWD
config ATLFWD_FWD
       bool "Enable forwarding-engine API"
       default n
       ---help---
       help

         Say Y to enable the forwarding-engine API

@@ -17,7 +17,7 @@ config ATLFWD_FWD_RXBUF
       range 0 320
       default 160 if ATLFWD_FWD
       default 0
       ---help---
       help

         Amount of Rx buffer to reserve for the forwarding-engine
         rings. This sets the default value of the fwd_rx_buf_reserve
@@ -32,7 +32,7 @@ config ATLFWD_FWD_TXBUF
       range 0 160
       default 80 if ATLFWD_FWD
       default 0
       ---help---
       help

         Amount of Tx buffer to reserve for the forwarding-engine
         rings. This sets the default value of the fwd_tx_buf_reserve
@@ -41,6 +41,14 @@ config ATLFWD_FWD_TXBUF
         Value in kiB, 0 to 320, defaults to 80 if forwarding-engine
         API enabled, 0 otherwise.

config ATLFWD_FWD_NETLINK
        bool "Enable netlink control socket for forwarding engine"
        default n
        depends on ATLFWD_FWD
        help

          Expose forwarding engine APIs over the netlink socket.

endif

config AQFWD_QCOM
+2 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ atlantic-fwd-objs := atl_fw.o \
		     atl_hwmon.o

atlantic-fwd-$(CONFIG_ATLFWD_FWD) += atl_fwd.o
atlantic-fwd-$(CONFIG_ATLFWD_FWD_NETLINK) += atl_fwdnl.o \
					      atl_fwdnl_params.o

atlantic-fwd-$(CONFIG_AQFWD_QCOM) += atl_qcom.o
atlantic-fwd-$(CONFIG_AQFWD_QCOM_IPA) += atl_qcom_ipa.o
+42 −59
Original line number Diff line number Diff line
@@ -18,74 +18,19 @@
#include <linux/netdevice.h>
#include <linux/moduleparam.h>

#define ATL_VERSION "1.0.25"
#define ATL_VERSION "1.0.27"

struct atl_nic;
enum atl_fwd_notify;

#include "atl_compat.h"
#include "atl_hw.h"
#include "atl_stats.h"

#define ATL_MAX_QUEUES 8

#include "atl_fwd.h"

struct atl_rx_ring_stats {
	uint64_t packets;
	uint64_t bytes;
	uint64_t linear_dropped;
	uint64_t alloc_skb_failed;
	uint64_t reused_head_page;
	uint64_t reused_data_page;
	uint64_t alloc_head_page;
	uint64_t alloc_data_page;
	uint64_t alloc_head_page_failed;
	uint64_t alloc_data_page_failed;
	uint64_t non_eop_descs;
	uint64_t mac_err;
	uint64_t csum_err;
	uint64_t multicast;
};

struct atl_tx_ring_stats {
	uint64_t packets;
	uint64_t bytes;
	uint64_t tx_busy;
	uint64_t tx_restart;
	uint64_t dma_map_failed;
};

struct atl_ring_stats {
	union {
		struct atl_rx_ring_stats rx;
		struct atl_tx_ring_stats tx;
	};
};

struct atl_ether_stats {
	uint64_t rx_pause;
	uint64_t tx_pause;
	uint64_t rx_ether_drops;
	uint64_t rx_ether_octets;
	uint64_t rx_ether_pkts;
	uint64_t rx_ether_broacasts;
	uint64_t rx_ether_multicasts;
	uint64_t rx_ether_crc_align_errs;
	uint64_t rx_filter_host;
	uint64_t rx_filter_lost;
};

struct atl_global_stats {
	struct atl_rx_ring_stats rx;
	struct atl_tx_ring_stats tx;

	/* MSM counters can't be reset without full HW reset, so
	 * store them in relative form:
	 * eth[i] == HW_counter - eth_base[i] */
	struct atl_ether_stats eth;
	struct atl_ether_stats eth_base;
};

enum {
	ATL_RXF_VLAN_BASE = 0,
	ATL_RXF_VLAN_MAX = ATL_VLAN_FLT_NUM,
@@ -214,6 +159,37 @@ struct atl_fwd {
	struct blocking_notifier_head nh_clients;
};

#ifdef CONFIG_ATLFWD_FWD_NETLINK
/* FWD ring descriptor
 * Similar to atl_desc_ring, but has less fields.
 *
 * Note: it's not a part of atl_fwd_ring on purpose.
 */
struct atl_fwd_ring_desc {
	struct atl_hw_ring hw;
	uint32_t head;
	uint32_t tail;
	union {
		struct atl_txbuf *txbufs;
	};
	struct u64_stats_sync syncp;
	struct atl_ring_stats stats;
	u32 tx_hw_head;
	struct atl_fwd_event tx_evt;
	struct atl_fwd_event rx_evt;
};

struct atl_fwdnl {
	struct atl_fwd_ring_desc ring_desc[ATL_NUM_FWD_RINGS * 2];
	/* State of forced redirections */
	int force_icmp_via;
	int force_tx_via;
	/* Deferred TX head cleanup */
	struct delayed_work *tx_cleanup_wq;
	u32 tx_bunch;
};
#endif /* CONFIG_ATLFWD_FWD_NETLINK */

struct atl_nic {
	struct net_device *ndev;

@@ -224,7 +200,7 @@ struct atl_nic {
	uint32_t priv_flags;
	struct timer_list work_timer;
	int max_mtu;
	int requested_nvecs;
	unsigned int requested_nvecs;
	int requested_rx_size;
	int requested_tx_size;
	int rx_intr_delay;
@@ -236,6 +212,9 @@ struct atl_nic {
#ifdef CONFIG_ATLFWD_FWD
	struct atl_fwd fwd;
#endif
#ifdef CONFIG_ATLFWD_FWD_NETLINK
	struct atl_fwdnl fwdnl;
#endif

	struct atl_rxf_ntuple rxf_ntuple;
	struct atl_rxf_vlan rxf_vlan;
@@ -305,10 +284,13 @@ extern const char atl_driver_name[];

extern const struct ethtool_ops atl_ethtool_ops;

extern int atl_max_queues;
extern unsigned int atl_max_queues;
extern unsigned atl_rx_linear;
extern unsigned atl_min_intr_delay;
extern int atl_enable_msi;
extern unsigned int atl_tx_clean_budget;
extern unsigned int atl_tx_free_low;
extern unsigned int atl_tx_free_high;

/* Logging conviniency macros.
 *
@@ -430,5 +412,6 @@ int atl_update_thermal(struct atl_hw *hw);
int atl_update_thermal_flag(struct atl_hw *hw, int bit, bool val);
int atl_verify_thermal_limits(struct atl_hw *hw, struct atl_thermal *thermal);
int atl_do_reset(struct atl_nic *nic);
int atl_set_media_detect(struct atl_nic *nic, bool on);

#endif
+50 −0
Original line number Diff line number Diff line
@@ -86,3 +86,53 @@ int atl_compat_pci_alloc_irq_vectors(struct pci_dev *dev,
}

#endif

#ifdef ATL_COMPAT_PCI_ENABLE_MSIX_RANGE
/* from commit 302a2523c277bea0bbe8340312b09507905849ed */
int atl_compat_pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
{
	int nvec = maxvec;
	int rc;

	if (maxvec < minvec)
		return -ERANGE;

	do {
		rc = pci_enable_msi_block(dev, nvec);
		if (rc < 0) {
			return rc;
		} else if (rc > 0) {
			if (rc < minvec)
				return -ENOSPC;
			nvec = rc;
		}
	} while (rc);

	return nvec;
}

int atl_compat_pci_enable_msix_range(struct pci_dev *dev,
				     struct msix_entry *entries,
				     int minvec, int maxvec)
{
	int nvec = maxvec;
	int rc;

	if (maxvec < minvec)
		return -ERANGE;

	do {
		rc = pci_enable_msix(dev, entries, nvec);
		if (rc < 0) {
			return rc;
		} else if (rc > 0) {
			if (rc < minvec)
				return -ENOSPC;
			nvec = rc;
		}
	} while (rc);

	return nvec;
}

#endif
+344 −35
Original line number Diff line number Diff line
@@ -17,17 +17,40 @@
#include <linux/pci.h>
#include <linux/msi.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
/* If the kernel is not RHEL / CentOS, then the 2 identifiers below will be
 * undefined. Define them this way to simplify the checks below.
 */
#ifndef RHEL_RELEASE_CODE
#define RHEL_RELEASE_CODE 0
#endif
#ifndef RHEL_RELEASE_VERSION
#define RHEL_RELEASE_VERSION(a,b) 1
#endif

/* introduced in commit 686fef928bba6be13cabe639f154af7d72b63120 */
static inline void timer_setup(struct timer_list *timer,
	void (*callback)(struct timer_list *), unsigned int flags)
{
	setup_timer(timer, (void (*)(unsigned long))callback,
			(unsigned long)timer);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
#define ATL_HAVE_MINMAX_MTU
#elif (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5)) && \
      (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,0))
#define ndo_change_mtu ndo_change_mtu_rh74
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) || RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)
/* introduced in commit 3f1ac7a700d039c61d8d8b99f28d605d489a60cf */
#define ATL_HAVE_ETHTOOL_KSETTINGS

/* introduced in commit 72bb68721f80a1441e871b6afc9ab0b3793d5031 */
#define ATL_HAVE_IPV6_NTUPLE
#endif

#endif	/* 4.14.0 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0) || RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)
/* introduced in commit 892311f66f2411b813ca631009356891a0c2b0a1 */
#define ATL_HAVE_RXHASH_TYPE
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) || RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)
/* introduced in commit 3de0b592394d17b2c41a261a6a493a521213f299 */
#define ATL_HAVE_ETHTOOL_RXHASH
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0)

@@ -46,21 +69,121 @@ static inline void timer_setup(struct timer_list *timer,
#define ETHTOOL_LINK_MODE_2500baseT_Full_BIT 47
#define ETHTOOL_LINK_MODE_5000baseT_Full_BIT 48

#else  /* 4.10.0 */
#endif	/* 4.10.0 */

#define ATL_HAVE_MINMAX_MTU
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)

#endif	/* 4.10.0 */
/* from commit 1dff8083a024650c75a9c961c38082473ceae8cf */
#define page_to_virt(x)	__va(PFN_PHYS(page_to_pfn(x)))
#endif	/* 4.7.0 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)

/* from commit be9d2e8927cef02076bb7b5b2637cd9f4be2e8df */
static inline int
pci_request_mem_regions(struct pci_dev *pdev, const char *name)
/* from commit d31eb342409b24e3d2e1989c775f3361e93acc08 */
/* Helpers to hide struct msi_desc implementation details */
#define msi_desc_to_dev(desc)		(&(desc)->dev.dev)
#define dev_to_msi_list(dev)		(&to_pci_dev((dev))->msi_list)
#define first_msi_entry(dev)		\
	list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list)
#define for_each_msi_entry(desc, dev)	\
	list_for_each_entry((desc), dev_to_msi_list((dev)), list)

#define first_pci_msi_entry(pdev)	first_msi_entry(&(pdev)->dev)
#define for_each_pci_msi_entry(desc, pdev)	\
	for_each_msi_entry((desc), &(pdev)->dev)

static inline struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
{
	return pci_request_selected_regions(pdev,
			    pci_select_bars(pdev, IORESOURCE_MEM), name);
	return desc->dev;
}

#endif	/* 3.19.0 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3)
/* ->xmit_more introduced in commit
 * 0b725a2ca61bedc33a2a63d0451d528b268cf975 for 3.18-rc1 */
static inline int skb_xmit_more(struct sk_buff *skb)
{
	return 0;
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
static inline int skb_xmit_more(struct sk_buff *skb)
{
	return netdev_xmit_more();
}
#else /* 3.18.0-5.2.0 for vanilla, anything less than 5.2.0 for RHEL */
static inline int skb_xmit_more(struct sk_buff *skb)
{
	return skb->xmit_more;
}
#endif	/* 3.18.0 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) &&                           \
	RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7, 3)
typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
				       struct sk_buff *skb);
static inline u16 atlfwd_nl_pick0(struct net_device *dev, struct sk_buff *skb)
{
	return 0;
}
#endif

/* NB! select_queue_fallback_t MUST be defined before #include on RHEL < 7.3 */
#include "atl_fwdnl.h"

#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) &&                           \
	RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7, 3)
static inline u16 atlfwd_nl_select_queue(struct net_device *dev,
					 struct sk_buff *skb)
{
	return atlfwd_nl_select_queue_fallback(dev, skb, NULL, atlfwd_nl_pick0);
}
#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) &&                         \
	RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7, 3)
static inline u16 atlfwd_nl_select_queue(struct net_device *dev,
					 struct sk_buff *skb, void *accel_priv)
{
	return atlfwd_nl_select_queue_fallback(
		dev, skb, (struct net_device *)accel_priv, atlfwd_nl_pick0);
}
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) &&                         \
	RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8, 0)
static inline u16 atlfwd_nl_select_queue(struct net_device *dev,
					 struct sk_buff *skb, void *accel_priv,
					 select_queue_fallback_t fallback)
{
	return atlfwd_nl_select_queue_fallback(
		dev, skb, (struct net_device *)accel_priv, fallback);
}
#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
static inline u16 atlfwd_nl_select_queue(struct net_device *dev,
					 struct sk_buff *skb,
					 struct net_device *sb_dev,
					 select_queue_fallback_t fallback)
{
	return atlfwd_nl_select_queue_fallback(dev, skb, sb_dev, fallback);
}
#else
static inline u16 atlfwd_nl_select_queue(struct net_device *dev,
					 struct sk_buff *skb,
					 struct net_device *sb_dev)
{
	return atlfwd_nl_select_queue_fallback(dev, skb, sb_dev,
					       netdev_pick_tx);
}
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,6)
/* introduced in commit 686fef928bba6be13cabe639f154af7d72b63120 */
static inline void timer_setup(struct timer_list *timer,
	void (*callback)(struct timer_list *), unsigned int flags)
{
	setup_timer(timer, (void (*)(unsigned long))callback,
			(unsigned long)timer);
}
#endif	/* 4.14.0 && RHEL < 7.6 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,5)

#define ATL_COMPAT_PCI_ALLOC_IRQ_VECTORS
int atl_compat_pci_alloc_irq_vectors(struct pci_dev *dev,
@@ -89,13 +212,19 @@ static inline void pci_free_irq_vectors(struct pci_dev *dev)
#define PCI_IRQ_MSI		(1 << 1) /* allow MSI interrupts */
#define PCI_IRQ_MSIX		(1 << 2) /* allow MSI-X interrupts */

#endif /* 4.8.0 */
#endif /* 4.8.0 && RHEL < 7.5 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,4)
/* from commit be9d2e8927cef02076bb7b5b2637cd9f4be2e8df */
static inline int
pci_request_mem_regions(struct pci_dev *pdev, const char *name)
{
	return pci_request_selected_regions(pdev,
			    pci_select_bars(pdev, IORESOURCE_MEM), name);
}
#endif /* 4.8.0 && RHEL < 7.4 */

/* from commit 1dff8083a024650c75a9c961c38082473ceae8cf */
#define page_to_virt(x)	__va(PFN_PHYS(page_to_pfn(x)))
#endif	/* 4.7.0 */
#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3)

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)

@@ -133,14 +262,6 @@ static inline void page_ref_inc(struct page *page)
#define IPV6_USER_FLOW 0x0e
#define IPV4_USER_FLOW IP_USER_FLOW

#else

/* introduced in commit 3f1ac7a700d039c61d8d8b99f28d605d489a60cf */
#define ATL_HAVE_ETHTOOL_KSETTINGS

/* introduced in commit 72bb68721f80a1441e871b6afc9ab0b3793d5031 */
#define ATL_HAVE_IPV6_NTUPLE

#endif	/* 4.6.0 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)
@@ -154,6 +275,24 @@ static inline int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)

#endif	/* 4.5.0 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)

/* introduced in 2f064f3485cd29633ad1b3cfb00cc519509a3d72
 * The new implementation can't be used directly as it requires
 * changes to linux/mm code. Use the old check described in the
 * commit with older kernels insted. It can lead to false positives,
 * but as we only use it to determine whether the page is re-usable,
 * the false positives can only decrease performance. */
static inline bool page_is_pfmemalloc(struct page *page)
{
	return page->pfmemalloc && !page->mapping;
}
#endif	/* 4.1.0 */

#endif /* RHEL_RELEASE_CODE < 7.3 */

#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,2)

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0)
#define ETHTOOL_RX_FLOW_SPEC_RING      0x00000000FFFFFFFFLL
#define ETHTOOL_RX_FLOW_SPEC_RING_VF   0x000000FF00000000LL
@@ -169,4 +308,174 @@ static inline __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
};
#endif /* 4.2.0 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0)

/* renamed in commit df8a39defad46b83694ea6dd868d332976d62cc0 */
#define skb_vlan_tag_present(__skb) vlan_tx_tag_present(__skb)
#define skb_vlan_tag_get(__skb) vlan_tx_tag_get(__skb)
#endif	/* 4.0.0 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)

/* introduced in commit 1077fa36f23e259858caf6f269a47393a5aff523
 * use plain rmb() for now*/
#define dma_rmb()	rmb()

/* from commit 9c0c112422a2a6b06fcddcaf21957676490cebba */
static inline int eth_skb_pad(struct sk_buff *skb)
{
	unsigned int len = ETH_ZLEN;
	unsigned int size = skb->len;

	if (unlikely(size < len)) {
		len -= size;
		if (skb_pad(skb, len))
			return -ENOMEM;
		__skb_put(skb, len);
	}
	return 0;
}

/* introduced in commit 71dfda58aaaf4bf6b1bc59f9d8afa635fa1337d4 */
#define __dev_alloc_pages(__flags, __order) __skb_alloc_pages(__flags | __GFP_COMP, NULL, __order)

/* introduced in commit fd11a83dd3630ec6a60f8a702446532c5c7e1991 */
#define napi_alloc_skb(__napi, __len) netdev_alloc_skb_ip_align((__napi)->dev, __len)

/* introduced in commit 3b47d30396bae4f0bd1ff0dbcd7c4f5077e7df4e */
#define napi_complete_done(__napi, __work_done) napi_complete(__napi)

/* introduced in commit bc9ad166e38ae1cdcb5323a8aa45dff834d68bfa */
#define napi_schedule_irqoff(__napi) napi_schedule(__napi)

/* READ_ONCE() / WRITE_ONCE
 * from commit 230fa253df6352af12ad0a16128760b5cb3f92df with changes
 * from 43239cbe79fc369f5d2160bd7f69e28b5c50a58c and
 * 7bd3e239d6c6d1cad276e8f130b386df4234dcd7 */

/* READ_ONCE / WRTIE_ONCE were also cherry-picked into 3.12.58 as
 * b5be8baf9e0d5ea035588a0430b2af4989e07572  and
 * dda458f0183649e8613a62bb59bec4e5acb883aa */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,58) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)

static __always_inline void __read_once_size(volatile void *p, void *res, int size)
{
	switch (size) {
	case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
	case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
	case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
	case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
	default:
		barrier();
		__builtin_memcpy((void *)res, (const void *)p, size);
		barrier();
	}
}

static __always_inline void __write_once_size(volatile void *p, void *res, int size)
{
	switch (size) {
	case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
	case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
	case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
	case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
	default:
		barrier();
		__builtin_memcpy((void *)p, (const void *)res, size);
		barrier();
	}
}

#define READ_ONCE(x)							\
	({ typeof(x) __val; __read_once_size(&x, &__val, sizeof(__val)); __val; })

#define WRITE_ONCE(x, val) \
	({ typeof(x) __val; __val = val; __write_once_size(&x, &__val, sizeof(__val)); __val; })

#endif	/* 3.12.58 */

#endif	/* 3.19.0 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)

/* introduced in commit 56193d1bce2b2759cb4bdcc00cd05544894a0c90
 * pull the whole head buffer len for now*/
#define eth_get_headlen(__data, __max_len) (__max_len)

#endif	/* 3.18.0 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)

/* from commit 286ab723d4b83d37deb4017008ef1444a95cfb0d */
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
}

/* introduced in commit e6247027e5173c00efb2084d688d06ff835bc3b0 */
#define dev_consume_skb_any(__skb) dev_kfree_skb_any(__skb)

/* from commit 09323cc479316e046931a2c679932204b36fea6c */
enum pkt_hash_types {
	PKT_HASH_TYPE_NONE,	/* Undefined type */
	PKT_HASH_TYPE_L2,	/* Input: src_MAC, dest_MAC */
	PKT_HASH_TYPE_L3,	/* Input: src_IP, dst_IP */
	PKT_HASH_TYPE_L4,	/* Input: src_IP, dst_IP, src_port, dst_port */
};

static inline void
skb_set_hash(struct sk_buff *skb, __u32 hash, enum pkt_hash_types type)
{
	skb->l4_rxhash = (type == PKT_HASH_TYPE_L4);
	skb->rxhash = hash;
}

/* from commit 302a2523c277bea0bbe8340312b09507905849ed */
#define ATL_COMPAT_PCI_ENABLE_MSIX_RANGE
int atl_compat_pci_enable_msi_range(struct pci_dev *dev, int minvec,
	int maxvec);
int atl_compat_pci_enable_msix_range(struct pci_dev *dev,
	struct msix_entry *entries, int minvec, int maxvec);

static inline int pci_enable_msi_range(struct pci_dev *dev, int minvec,
	int maxvec)
{
	return atl_compat_pci_enable_msi_range(dev, minvec, maxvec);
}

static inline int pci_enable_msix_range(struct pci_dev *dev,
	struct msix_entry *entries, int minvec, int maxvec)
{
	return atl_compat_pci_enable_msix_range(dev, entries, minvec, maxvec);
}

#endif	/* 3.14.0 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,27)

/* from commit 4aa806b771d16b810771d86ce23c4c3160888db3
 * also cherry-picked into 3.12-stable as
 * 8bac7a35e60ca70c8d12ddbfdf28a8df5a976b2b */
static inline int dma_set_mask_and_coherent(struct device *dev, u64 mask)
{
	int rc = dma_set_mask(dev, mask);
	if (rc == 0)
		dma_set_coherent_mask(dev, mask);
	return rc;
}

#endif	/* 3.12.27 */

#endif /* RHEL_RELEASE_CODE < 7.2 */

#endif
Loading