From 15319d4baca8feec47e729441cd75bb6158121c6 Mon Sep 17 00:00:00 2001 From: Vladimir Sokolovsky Date: Sun, 14 Dec 2014 13:12:50 +0200 Subject: [PATCH] Added staff to support RHEL6.x Signed-off-by: Vladimir Sokolovsky --- compat/compat-3.9.c | 47 ++++ config/rdma.m4 | 543 ++++++++++++++++++++++++++++++++++++- include/linux/compat-3.9.h | 32 ++- 3 files changed, 606 insertions(+), 16 deletions(-) diff --git a/compat/compat-3.9.c b/compat/compat-3.9.c index 9a06cd5..95047ee 100644 --- a/compat/compat-3.9.c +++ b/compat/compat-3.9.c @@ -24,7 +24,9 @@ #include #include +#ifdef CONFIG_XPS static u32 hashrnd __read_mostly; +#endif #define get_xps_queue LINUX_BACKPORT(get_xps_queue) static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb) @@ -87,3 +89,48 @@ u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb) return queue_index; } EXPORT_SYMBOL(__netdev_pick_tx); + +#define netif_set_xps_queue LINUX_BACKPORT(netif_set_xps_queue) +int netif_set_xps_queue(struct net_device *dev, struct cpumask *msk, u16 idx) +{ +#ifdef HAVE_XPS_MAP + int i, len, err; + char buf[MAX_XPS_BUFFER_SIZE]; + struct attribute *attr = NULL; + struct kobj_type *ktype = NULL; + struct mlx4_en_netq_attribute *xps_attr = NULL; + struct netdev_queue *txq = netdev_get_tx_queue(dev, idx); + +#ifdef HAVE_NET_DEVICE_EXTENDED_TX_EXT + struct netdev_tx_queue_extended *txq_ext = + netdev_extended(dev)->_tx_ext + idx; + ktype = txq_ext->kobj.ktype; +#else /* HAVE_NET_DEVICE_EXTENDED_TX_EXT */ + ktype = txq->kobj.ktype; +#endif /* HAVE_NET_DEVICE_EXTENDED_TX_EXT */ + if (!ktype) + return -ENOMEM; + + for (i = 0; (attr = ktype->default_attrs[i]); i++) { + if (!strcmp("xps_cpus", attr->name)) + break; + } + if (!attr) + return -EINVAL; + + len = bitmap_scnprintf(buf, MAX_XPS_BUFFER_SIZE, + cpumask_bits(msk), MAX_XPS_CPUS); + if (!len) + return -ENOMEM; + + xps_attr = to_netq_attr(attr); + err = xps_attr->store(txq, xps_attr, buf, len); + if (err) + return -EINVAL; + + return 0; +#else /* HAVE_XPS_MAP */ + return -1; +#endif /* HAVE_XPS_MAP */ +} +EXPORT_SYMBOL(netif_set_xps_queue); diff --git a/config/rdma.m4 b/config/rdma.m4 index 7f91887..d91d589 100644 --- a/config/rdma.m4 +++ b/config/rdma.m4 @@ -227,11 +227,67 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], ],[ AC_MSG_RESULT(no) ]) + + AC_MSG_CHECKING([if exist struct ethtool_ops_ext]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + const struct ethtool_ops_ext en_ethtool_ops_ext = { + .size = sizeof(struct ethtool_ops_ext), + }; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_ETHTOOL_OPS_EXT, 1, + [struct ethtool_ops_ext is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct ethtool_ops_ext has get/set_rxfh]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + const struct ethtool_ops_ext en_ethtool_ops_ext = { + .get_rxfh_indir_size = NULL, + .get_rxfh = NULL, + .set_rxfh = NULL, + }; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GET_SET_RXFH_OPS_EXT, 1, + [get/set_rxfh is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct ethtool_ops_ext has get/set_rxfh_indir]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + const struct ethtool_ops_ext en_ethtool_ops_ext = { + .get_rxfh_indir_size = NULL, + .get_rxfh_indir = NULL, + .set_rxfh_indir = NULL, + }; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GET_SET_RXFH_INDIR, 1, + [get/set_rxfh_indir is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + AC_MSG_CHECKING([if struct net_device has dev_port]) LB_LINUX_TRY_COMPILE([ #include ],[ - struct net_device *dev; + struct net_device *dev = NULL; dev->dev_port = 0; @@ -313,6 +369,8 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], ],[ select_queue_fallback_t fallback; + fallback = NULL; + return 0; ],[ AC_MSG_RESULT(yes) @@ -477,7 +535,7 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], LB_LINUX_TRY_COMPILE([ #include ],[ - struct netdev_phys_port_id x; + struct netdev_phys_port_id *x = NULL; return 0; ],[ @@ -642,6 +700,36 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_RESULT(no) ]) + AC_MSG_CHECKING([if struct skbuff.h has skb_inner_transport_header]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + skb_inner_transport_header(NULL); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SKB_INNER_TRANSPORT_HEADER, 1, + [skb_inner_transport_header is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct skbuff.h has skb_inner_network_header]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + skb_inner_network_header(NULL); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SKB_INNER_NETWORK_HEADER, 1, + [skb_inner_network_header is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + AC_MSG_CHECKING([if if_vlan.h has vlan_dev_get_egress_qos_mask]) LB_LINUX_TRY_COMPILE([ #include @@ -690,14 +778,14 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_CHECKING([if ndo_select_queue has accel_priv]) LB_LINUX_TRY_COMPILE([ #include - ],[ - struct net_device_opts ndops; static u16 select_queue(struct net_device *dev, struct sk_buff *skb, void *accel_priv) { return 0; } + ],[ + struct net_device_opts ndops; ndoops.ndo_select_queue = select_queue; @@ -749,7 +837,6 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], ],[ struct u64_stats_sync sync; u64_stats_init(&sync); - }; return 0; ],[ @@ -766,7 +853,6 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], ],[ struct u64_stats_sync sync; u64_stats_fetch_begin_irq(&sync); - }; return 0; ],[ @@ -781,9 +867,7 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], #include ],[ char dest[6], src[6]; - ether_addr_copy(&dest, &src); - - }; + ether_addr_copy(&dest, &src); return 0; ],[ @@ -797,13 +881,15 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_CHECKING([if struct net_device_ops has *ndo_set_vf_rate]) LB_LINUX_TRY_COMPILE([ #include - ],[ - struct net_device_ops netdev_ops; + int set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, int max_tx_rate) { return 0; } + ],[ + struct net_device_ops netdev_ops; + netdev_ops.ndo_set_vf_rate = set_vf_rate; return 0; ],[ @@ -814,6 +900,163 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_RESULT(no) ]) + AC_MSG_CHECKING([if netdev_extended has hw_features]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct net_device *dev = NULL; + + netdev_extended(dev)->hw_features = 0; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETDEV_EXTENDED_HW_FEATURES, 1, + [ is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if net_device_extended has _tx_ext]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct net_device *dev = NULL; + + netdev_extended(dev)->_tx_ext = NULL; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NET_DEVICE_EXTENDED_TX_EXT, 1, + [ is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if net_device_extended has ndo_busy_poll]) + LB_LINUX_TRY_COMPILE([ + #include + + int busy_poll(struct napi_struct *napi) + { + return 0; + } + ],[ + struct net_device *dev = NULL; + + netdev_extended(dev)->ndo_busy_poll = busy_poll; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETDEV_EXTENDED_NDO_BUSY_POLL, 1, + [ is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if netdevice.h has set_netdev_hw_features]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct net_device *dev = NULL; + + set_netdev_hw_features(dev, 0); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SET_NETDEV_HW_FEATURES, 1, + [ is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if netdevice.h has netif_set_xps_queue]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct net_device *dev = NULL; + + netif_set_xps_queue(dev, NULL, 0); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETIF_SET_XPS_QUEUE, 1, + [ is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + + AC_MSG_CHECKING([if struct net_device_ops has *ndo_set_features]) + LB_LINUX_TRY_COMPILE([ + #include + + int set_features(struct net_device *dev, netdev_features_t features) + { + return 0; + } + ],[ + struct net_device_ops netdev_ops; + + netdev_ops.ndo_set_features = set_features; + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NDO_SET_FEATURES, 1, + [ndo_set_features is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct net_device_ops has *ndo_setup_tc]) + LB_LINUX_TRY_COMPILE([ + #include + + int setup_tc(struct net_device *dev, , u8 tc) + { + return 0; + } + ],[ + struct net_device_ops netdev_ops; + + netdev_ops.ndo_setup_tc = setup_tc; + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NDO_SETUP_TC, 1, + [ndo_setup_tc is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct net_device_ops has *ndo_rx_flow_steer]) + LB_LINUX_TRY_COMPILE([ + #include + + int rx_flow_steer(struct net_device *dev, + const struct sk_buff *skb, + u16 rxq_index, + u32 flow_id) + { + return 0; + } + ],[ + struct net_device_ops netdev_ops; + + netdev_ops.ndo_rx_flow_steer = rx_flow_steer; + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NDO_RX_FLOW_STEER, 1, + [ndo_rx_flow_steer is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + AC_MSG_CHECKING([if struct net_device has priv_flags]) LB_LINUX_TRY_COMPILE([ #include @@ -833,14 +1076,15 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_CHECKING([if struct net_device_ops has *ndo_get_stats64]) LB_LINUX_TRY_COMPILE([ #include - ],[ - struct net_device_ops netdev_ops; + struct rtnl_link_stats64* get_stats_64(struct net_device *dev, struct rtnl_link_stats64 *storage) { struct rtnl_link_stats64 stats_64; return &stats_64; } + ],[ + struct net_device_ops netdev_ops; netdev_ops.ndo_get_stats64 = get_stats_64; @@ -873,12 +1117,14 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_CHECKING([if struct net_device_ops ndo_vlan_rx_add_vid has 3 parameters ]) LB_LINUX_TRY_COMPILE([ #include - ],[ - struct net_device_ops netdev_ops; + int vlan_rx_add_vid(struct net_device *dev,__be16 proto, u16 vid) { return 0; } + ],[ + struct net_device_ops netdev_ops; + netdev_ops.ndo_vlan_rx_add_vid = vlan_rx_add_vid; return 0; @@ -890,6 +1136,159 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_RESULT(no) ]) + AC_MSG_CHECKING([if net_device_ops has ndo_get_phys_port_id]) + LB_LINUX_TRY_COMPILE([ + #include + + int get_phys_port_id(struct net_device *dev, + struct netdev_phys_port_id *ppid) + { + return 0; + } + ],[ + struct net_device_ops netdev_ops; + + netdev_ops.ndo_get_phys_port_id = get_phys_port_id; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETDEV_NDO_GET_PHYS_PORT_ID, 1, + [ is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct net_device_ops_ext exist]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct net_device_ops_ext netdev_ops_ext; + struct net_device_ops_ext netdev_ops__ext = { + .size = sizeof(struct net_device_ops_ext), + }; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NET_DEVICE_OPS_EXT, 1, + [struct net_device_ops_ext is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if net_device_ops_ext has ndo_get_phys_port_id]) + LB_LINUX_TRY_COMPILE([ + #include + + int get_phys_port_id(struct net_device *dev, + struct netdev_phys_port_id *ppid) + { + return 0; + } + ],[ + struct net_device_ops_ext netdev_ops_ext; + + netdev_ops_ext.ndo_get_phys_port_id = get_phys_port_id; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETDEV_EXT_NDO_GET_PHYS_PORT_ID, 1, + [ndo_get_phys_port_id is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if net_device_ops has ndo_set_vf_spoofchk]) + LB_LINUX_TRY_COMPILE([ + #include + + int set_vf_spoofchk(struct net_device *dev, int vf, bool setting) + { + return 0; + } + ],[ + struct net_device_ops netdev_ops; + + netdev_ops.ndo_set_vf_spoofchk = set_vf_spoofchk; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETDEV_OPS_NDO_SET_VF_SPOOFCHK, 1, + [ndo_set_vf_spoofchk is defined in net_device_ops]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if net_device_ops_ext has ndo_set_vf_spoofchk]) + LB_LINUX_TRY_COMPILE([ + #include + + int set_vf_spoofchk(struct net_device *dev, int vf, bool setting) + { + return 0; + } + ],[ + struct net_device_ops_ext netdev_ops_ext; + + netdev_ops_ext.ndo_set_vf_spoofchk = set_vf_spoofchk; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETDEV_OPS_EXT_NDO_SET_VF_SPOOFCHK, 1, + [ndo_set_vf_spoofchk is defined in net_device_ops_ext]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if net_device_ops has ndo_set_vf_link_state]) + LB_LINUX_TRY_COMPILE([ + #include + + int set_vf_link_state(struct net_device *dev, int vf, int link_state) + { + return 0; + } + ],[ + struct net_device_ops netdev_ops; + + netdev_ops.ndo_set_vf_link_state = set_vf_link_state; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETDEV_OPS_NDO_SET_VF_LINK_STATE, 1, + [ndo_set_vf_link_state is defined in net_device_ops]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if net_device_ops_ext has ndo_set_vf_link_state]) + LB_LINUX_TRY_COMPILE([ + #include + + int set_vf_link_state(struct net_device *dev, int vf, int link_state) + { + return 0; + } + ],[ + struct net_device_ops_ext netdev_ops_ext; + + netdev_ops_ext.ndo_set_vf_link_state = set_vf_link_state; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETDEV_OPS_EXT_NDO_SET_VF_LINK_STATE, 1, + [ndo_set_vf_link_state is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if netdevice.h netif_set_real_num_tx_queues returns int]) LB_LINUX_TRY_COMPILE([ #include @@ -906,6 +1305,22 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_RESULT(no) ]) + AC_MSG_CHECKING([if struct netdevice.h has struct xps_map]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct xps_map map; + map.len = 0; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XPS_MAP, 1, + [struct xps_map is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + AC_MSG_CHECKING([if struct ethtool_ops has set_phys_id]) LB_LINUX_TRY_COMPILE([ #include @@ -941,6 +1356,58 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_RESULT(no) ]) + AC_MSG_CHECKING([if struct ethtool_ops_ext has get/set_channels]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + const struct ethtool_ops_ext en_ethtool_ops_ext = { + .get_channels = NULL, + .set_channels = NULL, + }; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GET_SET_CHANNELS_EXT, 1, + [get/set_channels is defined in ethtool_ops_ext]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct ethtool_ops has get_ts_info]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + const struct ethtool_ops en_ethtool_ops = { + .get_ts_info = NULL, + }; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GET_TS_INFO, 1, + [get_ts_info is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct ethtool_ops_ext has get_ts_info]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + const struct ethtool_ops_ext en_ethtool_ops_ext = { + .get_ts_info = NULL, + }; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GET_TS_INFO_EXT, 1, + [get_ts_info is defined in ethtool_ops_ext]) + ],[ + AC_MSG_RESULT(no) + ]) + AC_MSG_CHECKING([if netdevice.h has struct netdev_hw_addr]) LB_LINUX_TRY_COMPILE([ #include @@ -1017,6 +1484,38 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_RESULT(no) ]) + AC_MSG_CHECKING([if struct net_device has hw_enc_features]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct net_device dev; + dev.hw_enc_features = 0; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETDEV_HW_ENC_FEATURES, 1, + [hw_enc_features is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct net_device has rx_cpu_rmap]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct net_device dev; + dev.rx_cpu_rmap = NULL; + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NETDEV_RX_CPU_RMAP, 1, + [rx_cpu_rmap is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + AC_MSG_CHECKING([if if_vlan.h has vlan_hwaccel_receive_skb]) LB_LINUX_TRY_COMPILE([ #include @@ -1032,6 +1531,20 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], AC_MSG_RESULT(no) ]) + AC_MSG_CHECKING([if irqdesc.h has irq_desc_get_irq_data]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct irq_data *data = irq_desc_get_irq_data(NULL); + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_IRQ_DESC_GET_IRQ_DATA, 1, + [irq_desc_get_irq_data is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + AC_MSG_CHECKING([if pci_dev has pcie_mpss]) LB_LINUX_TRY_COMPILE([ diff --git a/include/linux/compat-3.9.h b/include/linux/compat-3.9.h index b9a45d4..94ace12 100644 --- a/include/linux/compat-3.9.h +++ b/include/linux/compat-3.9.h @@ -5,8 +5,38 @@ #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) -extern u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb); +#include +#include +#define __netdev_pick_tx LINUX_BACKPORT(__netdev_pick_tx) +u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb); + +#if NR_CPUS < 64 +#define MAX_XPS_CPUS NR_CPUS +#else +#define MAX_XPS_CPUS 64 +#endif /* NR_CPUS */ +#define mlx4_en_hashrnd 0xd631614b +#define MAX_XPS_BUFFER_SIZE (DIV_ROUND_UP(MAX_XPS_CPUS, 32) * 9) + +#ifndef HAVE_NETIF_SET_XPS_QUEUE + +struct mlx4_en_netq_attribute { + struct attribute attr; + ssize_t (*show)(struct netdev_queue *queue, + struct mlx4_en_netq_attribute *attr, char *buf); + ssize_t (*store)(struct netdev_queue *queue, + struct mlx4_en_netq_attribute *attr, const char *buf, + size_t len); +}; + +#define to_netq_attr(_attr) container_of(_attr, \ + struct mlx4_en_netq_attribute, attr) + +#define netif_set_xps_queue LINUX_BACKPORT(netif_set_xps_queue) +int netif_set_xps_queue(struct net_device *dev, struct cpumask *msk, u16 idx); + +#endif /* HAVE_NETIF_SET_XPS_QUEUE */ #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) */ #endif /* LINUX_3_9_COMPAT_H */ -- 2.41.0