drivers/net/ethernet/mellanox/mlx4/cmd.c | 6 +
drivers/net/ethernet/mellanox/mlx4/en_clock.c | 2 +
drivers/net/ethernet/mellanox/mlx4/en_cq.c | 11 ++
- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 58 +++++++-
+ drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c | 4 +
+ drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 62 +++++++-
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 199 +++++++++++++++++++++++
drivers/net/ethernet/mellanox/mlx4/en_rx.c | 84 ++++++++++-
- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 56 +++++++-
+ drivers/net/ethernet/mellanox/mlx4/en_tx.c | 61 +++++++-
drivers/net/ethernet/mellanox/mlx4/eq.c | 10 ++
drivers/net/ethernet/mellanox/mlx4/main.c | 24 +++
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 21 +++-
include/linux/mlx4/cq.h | 5 +
- 13 files changed, 506 insertions(+), 5 deletions(-)
+ 14 files changed, 519 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c
index xxxxxxx..xxxxxxx xxxxxx
irq_set_affinity_hint(cq->mcq.irq, NULL);
}
netif_napi_del(&cq->napi);
+diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
+index xxxxxxx..xxxxxxx xxxxxx
+--- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
+@@ -203,6 +203,7 @@ static u8 mlx4_en_dcbnl_setdcbx(struct net_device *dev, u8 mode)
+ return 0;
+ }
+
++#ifdef HAVE_IEEE_GET_SET_MAXRATE
+ #define MLX4_RATELIMIT_UNITS_IN_KB 100000 /* rate-limit HW unit in Kbps */
+ static int mlx4_en_dcbnl_ieee_getmaxrate(struct net_device *dev,
+ struct ieee_maxrate *maxrate)
+@@ -241,12 +242,15 @@ static int mlx4_en_dcbnl_ieee_setmaxrate(struct net_device *dev,
+
+ return 0;
+ }
++#endif
+
+ const struct dcbnl_rtnl_ops mlx4_en_dcbnl_ops = {
+ .ieee_getets = mlx4_en_dcbnl_ieee_getets,
+ .ieee_setets = mlx4_en_dcbnl_ieee_setets,
++#ifdef HAVE_IEEE_GET_SET_MAXRATE
+ .ieee_getmaxrate = mlx4_en_dcbnl_ieee_getmaxrate,
+ .ieee_setmaxrate = mlx4_en_dcbnl_ieee_setmaxrate,
++#endif
+ .ieee_getpfc = mlx4_en_dcbnl_ieee_getpfc,
+ .ieee_setpfc = mlx4_en_dcbnl_ieee_setpfc,
+
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index xxxxxxx..xxxxxxx xxxxxx
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
#define all_zeros_or_all_ones(field) \
((field) == 0 || (field) == (__force typeof(field))-1)
-@@ -1058,8 +1069,13 @@ static int mlx4_en_get_num_flows(struct mlx4_en_priv *priv)
+@@ -664,11 +675,13 @@ static int mlx4_en_validate_flow(struct net_device *dev,
+ if (cmd->fs.location >= MAX_NUM_OF_FS_RULES)
+ return -EINVAL;
+
++#ifdef HAVE_ETHTOOL_FLOW_EXT_H_DEST
+ if (cmd->fs.flow_type & FLOW_MAC_EXT) {
+ /* dest mac mask must be ff:ff:ff:ff:ff:ff */
+ if (!is_broadcast_ether_addr(cmd->fs.m_ext.h_dest))
+ return -EINVAL;
+ }
++#endif
+
+ switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
+ case TCP_V4_FLOW:
+@@ -760,9 +773,11 @@ static int mlx4_en_ethtool_add_mac_rule_by_ipv4(struct mlx4_en_priv *priv,
+ unsigned char mac[ETH_ALEN];
+
+ if (!ipv4_is_multicast(ipv4_dst)) {
++#ifdef HAVE_ETHTOOL_FLOW_EXT_H_DEST
+ if (cmd->fs.flow_type & FLOW_MAC_EXT)
+ memcpy(&mac, cmd->fs.h_ext.h_dest, ETH_ALEN);
+ else
++#endif
+ memcpy(&mac, priv->dev->dev_addr, ETH_ALEN);
+ } else {
+ ip_eth_mc_map(ipv4_dst, mac);
+@@ -1058,8 +1073,13 @@ static int mlx4_en_get_num_flows(struct mlx4_en_priv *priv)
}
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
-@@ -1087,7 +1103,11 @@ static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+@@ -1087,7 +1107,11 @@ static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
while ((!err || err == -ENOENT) && priority < cmd->rule_cnt) {
err = mlx4_en_get_flow(dev, cmd, i);
if (!err)
i++;
}
err = 0;
-@@ -1125,6 +1145,7 @@ static int mlx4_en_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+@@ -1125,6 +1149,7 @@ static int mlx4_en_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
return err;
}
static void mlx4_en_get_channels(struct net_device *dev,
struct ethtool_channels *channel)
{
-@@ -1174,8 +1195,12 @@ static int mlx4_en_set_channels(struct net_device *dev,
+@@ -1174,8 +1199,12 @@ static int mlx4_en_set_channels(struct net_device *dev,
netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num);
en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num);
-@@ -1192,7 +1217,9 @@ out:
+@@ -1192,7 +1221,9 @@ out:
mutex_unlock(&mdev->state_lock);
return err;
}
static int mlx4_en_get_ts_info(struct net_device *dev,
struct ethtool_ts_info *info)
{
-@@ -1224,6 +1251,7 @@ static int mlx4_en_get_ts_info(struct net_device *dev,
+@@ -1224,6 +1255,7 @@ static int mlx4_en_get_ts_info(struct net_device *dev,
return ret;
}
static int mlx4_en_set_priv_flags(struct net_device *dev, u32 flags)
{
-@@ -1267,6 +1295,7 @@ static u32 mlx4_en_get_priv_flags(struct net_device *dev)
+@@ -1267,6 +1299,7 @@ static u32 mlx4_en_get_priv_flags(struct net_device *dev)
return priv->pflags;
}
static int mlx4_en_get_tunable(struct net_device *dev,
const struct ethtool_tunable *tuna,
void *data)
-@@ -1308,7 +1337,7 @@ static int mlx4_en_set_tunable(struct net_device *dev,
+@@ -1308,7 +1341,7 @@ static int mlx4_en_set_tunable(struct net_device *dev,
return ret;
}
const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_drvinfo = mlx4_en_get_drvinfo,
-@@ -1331,18 +1360,43 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
+@@ -1331,18 +1364,43 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
.set_ringparam = mlx4_en_set_ringparam,
.get_rxnfc = mlx4_en_get_rxnfc,
.set_rxnfc = mlx4_en_set_rxnfc,
if (shinfo->gso_size) {
*inline_ok = false;
-+#ifdef HAVE_SKB_INNER_TRANSPORT_HEADER
++#if defined(HAVE_SKB_INNER_NETWORK_HEADER) && defined(HAVE_SK_BUFF_ENCAPSULATION)
if (skb->encapsulation)
*lso_header_size = (skb_inner_transport_header(skb) - skb->data) + inner_tcp_hdrlen(skb);
else
tx_info->ts_requested = 1;
}
-@@ -894,6 +940,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
+@@ -836,11 +882,16 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
+ * whether LSO is used */
+ tx_desc->ctrl.srcrb_flags = priv->ctrl_flags;
+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
++#ifdef HAVE_SK_BUFF_ENCAPSULATION
+ if (!skb->encapsulation)
+ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
+ MLX4_WQE_CTRL_TCP_UDP_CSUM);
+ else
+ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM);
++#else
++ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
++ MLX4_WQE_CTRL_TCP_UDP_CSUM);
++#endif
+ ring->tx_csum++;
+ }
+
+@@ -894,6 +945,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
build_inline_wqe(tx_desc, skb, shinfo, real_size, &vlan_tag,
tx_ind, fragptr);
-+#ifdef HAVE_SKB_INNER_NETWORK_HEADER
++#if defined(HAVE_SKB_INNER_NETWORK_HEADER) && defined(HAVE_SK_BUFF_ENCAPSULATION)
if (skb->encapsulation) {
struct iphdr *ipv4 = (struct iphdr *)skb_inner_network_header(skb);
if (ipv4->protocol == IPPROTO_TCP || ipv4->protocol == IPPROTO_UDP)
-@@ -901,6 +948,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
+@@ -901,6 +953,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
else
op_own |= cpu_to_be32(MLX4_WQE_CTRL_IIP);
}
ring->prod += nr_txbb;
-@@ -917,7 +965,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
+@@ -917,7 +970,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
netif_tx_stop_queue(ring->tx_queue);
ring->queue_stopped++;
}
real_size = (real_size / 16) & 0x3f;
-@@ -956,8 +1008,10 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
+@@ -956,8 +1013,10 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
wmb();
iowrite32(ring->doorbell_qpn,
ring->bf.uar->map + MLX4_SEND_DOORBELL);