diff mbox series

[SRU,Trusty,2/6] UBUNTU: SAUCE: i40e_bpo: Add a compatibility layer

Message ID 20180831112921.20457-3-juergh@canonical.com
State New
Headers show
Series i40e NIC not recognized (LP: #1789215) | expand

Commit Message

Juerg Haefliger Aug. 31, 2018, 11:29 a.m. UTC
BugLink: https://bugs.launchpad.net/bugs/1789215

Add a compatibility layer so that the 4.4 driver can be compilef for a
3.13 kernel.

Signed-off-by: Juerg Haefliger <juergh@canonical.com>
---
 ubuntu/i40e/Makefile           |  4 +++
 ubuntu/i40e/i40e.h             |  1 +
 ubuntu/i40e/i40e_ethtool.c     |  4 +++
 ubuntu/i40e/i40e_main.c        | 37 +++++++++++++++++++
 ubuntu/i40e/i40e_osdep.h       |  2 ++
 ubuntu/i40e/i40e_ptp.c         |  5 +++
 ubuntu/i40e/i40e_txrx.c        |  6 ++++
 ubuntu/i40e/i40e_virtchnl_pf.c | 10 ++++++
 ubuntu/i40e/i40e_virtchnl_pf.h |  4 +++
 ubuntu/i40e/kcompat.c          | 19 ++++++++++
 ubuntu/i40e/kcompat.h          | 65 ++++++++++++++++++++++++++++++++++
 11 files changed, 157 insertions(+)
 create mode 100644 ubuntu/i40e/kcompat.c
 create mode 100644 ubuntu/i40e/kcompat.h
diff mbox series

Patch

diff --git a/ubuntu/i40e/Makefile b/ubuntu/i40e/Makefile
index b4729ba57c9c..a7f1aedc9551 100644
--- a/ubuntu/i40e/Makefile
+++ b/ubuntu/i40e/Makefile
@@ -28,6 +28,8 @@ 
 # Makefile for the Intel(R) Ethernet Connection XL710 (i40e.ko) driver
 #
 
+ccflags-y := -DXENIAL_BPO
+
 obj-$(CONFIG_I40E) += i40e.o
 
 i40e-objs := i40e_main.o \
@@ -45,3 +47,5 @@  i40e-objs := i40e_main.o \
 
 i40e-$(CONFIG_I40E_DCB) += i40e_dcb.o i40e_dcb_nl.o
 i40e-$(CONFIG_I40E_FCOE) += i40e_fcoe.o
+
+i40e-y += kcompat.o
diff --git a/ubuntu/i40e/i40e.h b/ubuntu/i40e/i40e.h
index 8e84819c68ea..be954a49660f 100644
--- a/ubuntu/i40e/i40e.h
+++ b/ubuntu/i40e/i40e.h
@@ -53,6 +53,7 @@ 
 #include <linux/clocksource.h>
 #include <linux/net_tstamp.h>
 #include <linux/ptp_clock_kernel.h>
+#include "kcompat.h"
 #include "i40e_type.h"
 #include "i40e_prototype.h"
 #ifdef I40E_FCOE
diff --git a/ubuntu/i40e/i40e_ethtool.c b/ubuntu/i40e/i40e_ethtool.c
index 45869aa40d34..7386fb888aab 100644
--- a/ubuntu/i40e/i40e_ethtool.c
+++ b/ubuntu/i40e/i40e_ethtool.c
@@ -2636,6 +2636,7 @@  static int i40e_set_channels(struct net_device *dev,
 		return -EINVAL;
 }
 
+#ifndef XENIAL_BPO
 /**
  * i40e_get_rxfh_key_size - get the RSS hash key size
  * @netdev: network interface device structure
@@ -2735,6 +2736,7 @@  static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
 	return i40e_config_rss(vsi, seed, vsi->rss_lut_user,
 			       I40E_HLUT_ARRAY_SIZE);
 }
+#endif /* XENIAL_BPO */
 
 /**
  * i40e_get_priv_flags - report device private flags
@@ -2867,10 +2869,12 @@  static const struct ethtool_ops i40e_ethtool_ops = {
 	.get_ethtool_stats	= i40e_get_ethtool_stats,
 	.get_coalesce		= i40e_get_coalesce,
 	.set_coalesce		= i40e_set_coalesce,
+#ifndef XENIAL_BPO
 	.get_rxfh_key_size	= i40e_get_rxfh_key_size,
 	.get_rxfh_indir_size	= i40e_get_rxfh_indir_size,
 	.get_rxfh		= i40e_get_rxfh,
 	.set_rxfh		= i40e_set_rxfh,
+#endif /* XENIAL_BPO */
 	.get_channels		= i40e_get_channels,
 	.set_channels		= i40e_set_channels,
 	.get_ts_info		= i40e_get_ts_info,
diff --git a/ubuntu/i40e/i40e_main.c b/ubuntu/i40e/i40e_main.c
index 89c6b2d94431..0456b9d5d99d 100644
--- a/ubuntu/i40e/i40e_main.c
+++ b/ubuntu/i40e/i40e_main.c
@@ -4570,6 +4570,7 @@  static u8 i40e_dcb_get_enabled_tc(struct i40e_dcbx_config *dcbcfg)
 	return enabled_tc;
 }
 
+#ifndef XENIAL_BPO
 /**
  * i40e_pf_get_num_tc - Get enabled traffic classes for PF
  * @pf: PF being queried
@@ -4605,6 +4606,7 @@  static u8 i40e_pf_get_num_tc(struct i40e_pf *pf)
 	}
 	return num_tc;
 }
+#endif /* XENIAL_BPO */
 
 /**
  * i40e_pf_get_default_tc - Get bitmap for first enabled TC
@@ -5276,6 +5278,7 @@  void i40e_down(struct i40e_vsi *vsi)
 	}
 }
 
+#ifndef XENIAL_BPO
 /**
  * i40e_setup_tc - configure multiple traffic classes
  * @netdev: net device to configure
@@ -5346,6 +5349,7 @@  static int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
 		return -EINVAL;
 	return i40e_setup_tc(netdev, tc->tc);
 }
+#endif /* XENIAL_BPO */
 
 /**
  * i40e_open - Called when a network interface is made active
@@ -8829,10 +8833,16 @@  static int i40e_get_phys_port_id(struct net_device *netdev,
  * @addr: the MAC address entry being added
  * @flags: instructions from stack about fdb operation
  */
+#ifdef XENIAL_BPO
+static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
+			    struct net_device *dev,
+			    const unsigned char *addr, u16 flags)
+#else
 static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 			    struct net_device *dev,
 			    const unsigned char *addr, u16 vid,
 			    u16 flags)
+#endif /* XENIAL_BPO */
 {
 	struct i40e_netdev_priv *np = netdev_priv(dev);
 	struct i40e_pf *pf = np->vsi->back;
@@ -8841,10 +8851,12 @@  static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 	if (!(pf->flags & I40E_FLAG_SRIOV_ENABLED))
 		return -EOPNOTSUPP;
 
+#ifndef XENIAL_BPO
 	if (vid) {
 		pr_info("%s: vlans aren't supported yet for dev_uc|mc_add()\n", dev->name);
 		return -EINVAL;
 	}
+#endif /* XENIAL_BPO */
 
 	/* Hardware does not support aging addresses so if a
 	 * ndm_state is given only allow permanent addresses
@@ -8880,9 +8892,14 @@  static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
  * allow rebuild of the components with required hardware
  * bridge mode enabled.
  **/
+#ifdef XENIAL_BPO
+static int i40e_ndo_bridge_setlink(struct net_device *dev,
+				   struct nlmsghdr *nlh)
+#else
 static int i40e_ndo_bridge_setlink(struct net_device *dev,
 				   struct nlmsghdr *nlh,
 				   u16 flags)
+#endif /* XENIAL_BPO */
 {
 	struct i40e_netdev_priv *np = netdev_priv(dev);
 	struct i40e_vsi *vsi = np->vsi;
@@ -8954,10 +8971,16 @@  static int i40e_ndo_bridge_setlink(struct net_device *dev,
  * Return the mode in which the hardware bridge is operating in
  * i.e VEB or VEPA.
  **/
+#ifdef XENIAL_BPO
+static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+				   struct net_device *dev,
+				   u32 __always_unused filter_mask)
+#else
 static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
 				   struct net_device *dev,
 				   u32 __always_unused filter_mask,
 				   int nlflags)
+#endif /* XENIAL_BPO */
 {
 	struct i40e_netdev_priv *np = netdev_priv(dev);
 	struct i40e_vsi *vsi = np->vsi;
@@ -8978,10 +9001,15 @@  static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
 	if (!veb)
 		return 0;
 
+#ifdef XENIAL_BPO
+	return ndo_dflt_bridge_getlink(skb, pid, seq, dev, veb->bridge_mode);
+#else
 	return ndo_dflt_bridge_getlink(skb, pid, seq, dev, veb->bridge_mode,
 				       0, 0, nlflags, filter_mask, NULL);
+#endif /* XENIAL_BPO */
 }
 
+#ifndef XENIAL_BPO
 /* Hardware supports L4 tunnel length of 128B (=2^7) which includes
  * inner mac plus all inner ethertypes.
  */
@@ -9003,6 +9031,7 @@  static netdev_features_t i40e_features_check(struct sk_buff *skb,
 
 	return features;
 }
+#endif /* XENIAL_BPO */
 
 static const struct net_device_ops i40e_netdev_ops = {
 	.ndo_open		= i40e_open,
@@ -9020,7 +9049,9 @@  static const struct net_device_ops i40e_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= i40e_netpoll,
 #endif
+#ifndef XENIAL_BPO
 	.ndo_setup_tc		= __i40e_setup_tc,
+#endif /* XENIAL_BPO */
 #ifdef I40E_FCOE
 	.ndo_fcoe_enable	= i40e_fcoe_enable,
 	.ndo_fcoe_disable	= i40e_fcoe_disable,
@@ -9028,7 +9059,11 @@  static const struct net_device_ops i40e_netdev_ops = {
 	.ndo_set_features	= i40e_set_features,
 	.ndo_set_vf_mac		= i40e_ndo_set_vf_mac,
 	.ndo_set_vf_vlan	= i40e_ndo_set_vf_port_vlan,
+#ifdef XENIAL_BPO
+	.ndo_set_vf_tx_rate	= i40e_ndo_set_vf_bw,
+#else
 	.ndo_set_vf_rate	= i40e_ndo_set_vf_bw,
+#endif /* XENIAL_BPO */
 	.ndo_get_vf_config	= i40e_ndo_get_vf_config,
 	.ndo_set_vf_link_state	= i40e_ndo_set_vf_link_state,
 	.ndo_set_vf_spoofchk	= i40e_ndo_set_vf_spoofchk,
@@ -9042,7 +9077,9 @@  static const struct net_device_ops i40e_netdev_ops = {
 #endif
 	.ndo_get_phys_port_id	= i40e_get_phys_port_id,
 	.ndo_fdb_add		= i40e_ndo_fdb_add,
+#ifndef XENIAL_BPO
 	.ndo_features_check	= i40e_features_check,
+#endif /* XENIAL_BPO */
 	.ndo_bridge_getlink	= i40e_ndo_bridge_getlink,
 	.ndo_bridge_setlink	= i40e_ndo_bridge_setlink,
 };
diff --git a/ubuntu/i40e/i40e_osdep.h b/ubuntu/i40e/i40e_osdep.h
index 5b6feb7edeb1..f1fd74088748 100644
--- a/ubuntu/i40e/i40e_osdep.h
+++ b/ubuntu/i40e/i40e_osdep.h
@@ -34,8 +34,10 @@ 
 #include <linux/pci.h>
 #include <linux/highuid.h>
 
+#ifndef XENIAL_BPO
 /* get readq/writeq support for 32 bit kernels, use the low-first version */
 #include <linux/io-64-nonatomic-lo-hi.h>
+#endif /* XENIAL_BPO */
 
 /* File to be the magic between shared code and
  * actual OS primitives
diff --git a/ubuntu/i40e/i40e_ptp.c b/ubuntu/i40e/i40e_ptp.c
index 565ca7c835bc..40f9bdc66955 100644
--- a/ubuntu/i40e/i40e_ptp.c
+++ b/ubuntu/i40e/i40e_ptp.c
@@ -612,8 +612,13 @@  static long i40e_ptp_create_clock(struct i40e_pf *pf)
 	pf->ptp_caps.pps = 0;
 	pf->ptp_caps.adjfreq = i40e_ptp_adjfreq;
 	pf->ptp_caps.adjtime = i40e_ptp_adjtime;
+#ifdef XENIAL_BPO
+	pf->ptp_caps.gettime = i40e_ptp_gettime;
+	pf->ptp_caps.settime = i40e_ptp_settime;
+#else
 	pf->ptp_caps.gettime64 = i40e_ptp_gettime;
 	pf->ptp_caps.settime64 = i40e_ptp_settime;
+#endif /* XENIAL_BPO */
 	pf->ptp_caps.enable = i40e_ptp_feature_enable;
 
 	/* Attempt to register the clock before enabling the hardware. */
diff --git a/ubuntu/i40e/i40e_txrx.c b/ubuntu/i40e/i40e_txrx.c
index 30ee67ed2649..9128bdbdeb8e 100644
--- a/ubuntu/i40e/i40e_txrx.c
+++ b/ubuntu/i40e/i40e_txrx.c
@@ -1445,7 +1445,9 @@  static inline void i40e_rx_checksum(struct i40e_vsi *vsi,
 		     (rx_ptype <= I40E_RX_PTYPE_GRENAT6_MACVLAN_IPV6_ICMP_PAY4);
 
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
+#ifndef XENIAL_BPO
 	skb->csum_level = ipv4_tunnel || ipv6_tunnel;
+#endif /* XENIAL_BPO */
 
 	return;
 
@@ -2826,6 +2828,7 @@  static inline void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
 	 * pending and interrupts were disabled the service task will
 	 * trigger a force WB.
 	 */
+#ifndef XENIAL_BPO
 	if (skb->xmit_more  &&
 	    !netif_xmit_stopped(netdev_get_tx_queue(tx_ring->netdev,
 						    tx_ring->queue_index))) {
@@ -2839,10 +2842,13 @@  static inline void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
 		   (desc_count < WB_STRIDE)) {
 		tx_ring->packet_stride++;
 	} else {
+#endif /* XENIAL_BPO */
 		tx_ring->packet_stride = 0;
 		tx_ring->flags &= ~I40E_TXR_FLAGS_LAST_XMIT_MORE_SET;
 		do_rs = true;
+#ifndef XENIAL_BPO
 	}
+#endif /* XENIAL_BPO */
 	if (do_rs)
 		tx_ring->packet_stride = 0;
 
diff --git a/ubuntu/i40e/i40e_virtchnl_pf.c b/ubuntu/i40e/i40e_virtchnl_pf.c
index acd2693a4e97..c4f6712f131f 100644
--- a/ubuntu/i40e/i40e_virtchnl_pf.c
+++ b/ubuntu/i40e/i40e_virtchnl_pf.c
@@ -2277,8 +2277,12 @@  error_pvid:
  *
  * configure VF Tx rate
  **/
+#ifdef XENIAL_BPO
+int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int max_tx_rate)
+#else
 int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
 		       int max_tx_rate)
+#endif /* XENIAL_BPO */
 {
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
 	struct i40e_pf *pf = np->vsi->back;
@@ -2294,11 +2298,13 @@  int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
 		goto error;
 	}
 
+#ifndef XENIAL_BPO
 	if (min_tx_rate) {
 		dev_err(&pf->pdev->dev, "Invalid min tx rate (%d) (greater than 0) specified for VF %d.\n",
 			min_tx_rate, vf_id);
 		return -EINVAL;
 	}
+#endif /* XENIAL_BPO */
 
 	vf = &(pf->vf[vf_id]);
 	vsi = pf->vsi[vf->lan_vsi_idx];
@@ -2391,8 +2397,12 @@  int i40e_ndo_get_vf_config(struct net_device *netdev,
 
 	ether_addr_copy(ivi->mac, vf->default_lan_addr.addr);
 
+#ifdef XENIAL_BPO
+	ivi->tx_rate = vf->tx_rate;
+#else
 	ivi->max_tx_rate = vf->tx_rate;
 	ivi->min_tx_rate = 0;
+#endif /* XENIAL_BPO */
 	ivi->vlan = le16_to_cpu(vsi->info.pvid) & I40E_VLAN_MASK;
 	ivi->qos = (le16_to_cpu(vsi->info.pvid) & I40E_PRIORITY_MASK) >>
 		   I40E_VLAN_PRIORITY_SHIFT;
diff --git a/ubuntu/i40e/i40e_virtchnl_pf.h b/ubuntu/i40e/i40e_virtchnl_pf.h
index e74642a0c42e..509816079895 100644
--- a/ubuntu/i40e/i40e_virtchnl_pf.h
+++ b/ubuntu/i40e/i40e_virtchnl_pf.h
@@ -121,8 +121,12 @@  void i40e_vc_notify_vf_reset(struct i40e_vf *vf);
 int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac);
 int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
 			      int vf_id, u16 vlan_id, u8 qos);
+#ifdef XENIAL_BPO
+int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate);
+#else
 int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
 		       int max_tx_rate);
+#endif /* XENIAL_BPO */
 int i40e_ndo_get_vf_config(struct net_device *netdev,
 			   int vf_id, struct ifla_vf_info *ivi);
 int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link);
diff --git a/ubuntu/i40e/kcompat.c b/ubuntu/i40e/kcompat.c
new file mode 100644
index 000000000000..a4ad5e1d26fa
--- /dev/null
+++ b/ubuntu/i40e/kcompat.c
@@ -0,0 +1,19 @@ 
+/*
+ * Compatibility layer
+ * Copyright (c) 2018 Juerg Haefliger <juergh@canonical.com>
+ */
+
+#include <linux/net.h>
+
+/* cherry picked from v4.4 include/linux/netdevice.h */
+#define NETDEV_RSS_KEY_LEN 52
+
+/* backported from v4.4 net/core/ethtool.c */
+void netdev_rss_key_fill(void *buffer, size_t len)
+{
+	static u8 netdev_rss_key[NETDEV_RSS_KEY_LEN];
+
+	BUG_ON(len > NETDEV_RSS_KEY_LEN);
+	net_get_random_once(netdev_rss_key, sizeof(netdev_rss_key));
+	memcpy(buffer, netdev_rss_key, len);
+}
diff --git a/ubuntu/i40e/kcompat.h b/ubuntu/i40e/kcompat.h
new file mode 100644
index 000000000000..6fb20203e3ab
--- /dev/null
+++ b/ubuntu/i40e/kcompat.h
@@ -0,0 +1,65 @@ 
+/*
+ * Compatibility layer
+ * Copyright (c) 2018 Juerg Haefliger <juergh@canonical.com>
+ */
+
+#ifndef _KCOMPAT_H_
+#define _KCOMPAT_H_
+
+#define napi_schedule_irqoff	napi_schedule
+
+#define smp_mb__before_atomic	smp_mb
+#define smp_mb__after_atomic	smp_mb
+
+#define netdev_phys_item_id	netdev_phys_port_id
+
+#define NETIF_F_GSO_UDP_TUNNEL_CSUM	0
+#define NETIF_F_SCTP_CRC		NETIF_F_SCTP_CSUM
+
+#define SKB_GSO_UDP_TUNNEL_CSUM	0
+
+#define hlist_add_behind(a, b)	hlist_add_after((b), (a))
+
+#define dev_consume_skb_any	dev_kfree_skb_any
+
+#define dma_rmb	rmb
+
+#define napi_complete_done(napi, work_done)	napi_complete((napi))
+
+#define skb_vlan_tag_present	vlan_tx_tag_present
+#define skb_vlan_tag_get	vlan_tx_tag_get
+
+#define timespec64		timespec
+#define ns_to_timespec64	ns_to_timespec
+#define timespec64_to_ns	timespec_to_ns
+#define timespec64_add		timespec_add
+#define ktime_to_timespec64	ktime_to_timespec
+
+/* cherry picked from v4.4 include/linux/skbuff.h */
+static inline int skb_put_padto(struct sk_buff *skb, unsigned int len)
+{
+	unsigned int size = skb->len;
+
+	if (unlikely(size < len)) {
+		len -= size;
+		if (skb_pad(skb, len))
+			return -ENOMEM;
+		__skb_put(skb, len);
+	}
+	return 0;
+}
+
+/*
+ * backported from v4.9 net/ethernet/eth.c
+ * 3.13 doesn't support CONFIG_OF so the function always returns -ENODEV
+ */
+static inline int eth_platform_get_mac_address(struct device *dev,
+					       u8 *mac_addr)
+{
+	return -ENODEV;
+}
+
+/* The following are defined in kompat.c */
+extern void netdev_rss_key_fill(void *buffer, size_t len);
+
+#endif /* _KCOMPAT_H_ */