Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.com>
---
drivers/infiniband/hw/mlx4/main.c | 19 +
- drivers/net/ethernet/mellanox/mlx4/cmd.c | 6 +
+ drivers/net/ethernet/mellanox/mlx4/cmd.c | 9 +
drivers/net/ethernet/mellanox/mlx4/en_clock.c | 31 ++
drivers/net/ethernet/mellanox/mlx4/en_cq.c | 5 +
drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c | 19 +
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 488 +++++++++++++++++++++++-
drivers/net/ethernet/mellanox/mlx4/en_main.c | 4 +
- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 229 +++++++++++
+ drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 245 ++++++++++++
drivers/net/ethernet/mellanox/mlx4/en_rx.c | 76 ++++
drivers/net/ethernet/mellanox/mlx4/en_tx.c | 54 +++
drivers/net/ethernet/mellanox/mlx4/intf.c | 4 +
drivers/net/ethernet/mellanox/mlx4/pd.c | 4 +
include/linux/mlx4/cmd.h | 2 +
include/linux/mlx4/device.h | 4 +
- 17 files changed, 1042 insertions(+), 3 deletions(-)
+ 17 files changed, 1061 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index xxxxxxx..xxxxxxx xxxxxx
int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf)
{
struct mlx4_priv *priv = mlx4_priv(dev);
-@@ -3118,18 +3119,21 @@ int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_in
+@@ -3117,19 +3118,25 @@ int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_in
+
ivf->vlan = s_info->default_vlan;
ivf->qos = s_info->default_qos;
++#ifdef HAVE_VF_VLAN_PROTO
++ ivf->vlan_proto = htons(ETH_P_8021Q);
++#endif
+#ifdef HAVE_TX_RATE_LIMIT
if (mlx4_is_vf_vst_and_prio_qos(dev, port, s_info))
int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state)
{
-@@ -3235,6 +3239,7 @@ if_stat_out:
+@@ -3235,6 +3242,7 @@ if_stat_out:
}
EXPORT_SYMBOL_GPL(mlx4_get_counter_stats);
int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
struct ifla_vf_stats *vf_stats)
{
-@@ -3264,6 +3269,7 @@ int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
+@@ -3264,6 +3272,7 @@ int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
return err;
}
EXPORT_SYMBOL_GPL(mlx4_get_vf_stats);
dev->mtu = new_mtu;
if (netif_running(dev)) {
-@@ -2408,6 +2444,7 @@ static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos)
+@@ -2400,14 +2436,27 @@ static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
+ return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64);
+ }
+
++#if defined(HAVE_NDO_SET_VF_VLAN) || defined(HAVE_NDO_SET_VF_VLAN_EXTENDED)
++#ifdef HAVE_VF_VLAN_PROTO
++static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
++ __be16 vlan_proto)
++#else
+ static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos)
++#endif
+ {
+ struct mlx4_en_priv *en_priv = netdev_priv(dev);
+ struct mlx4_en_dev *mdev = en_priv->mdev;
+
++#ifdef HAVE_VF_VLAN_PROTO
++ if (vlan_proto != htons(ETH_P_8021Q))
++ return -EPROTONOSUPPORT;
++#endif
++
return mlx4_set_vf_vlan(mdev->dev, en_priv->port, vf, vlan, qos);
}
++#endif /* HAVE_NDO_SET_VF_VLAN */
+#ifdef HAVE_TX_RATE_LIMIT
static int mlx4_en_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
int max_tx_rate)
{
-@@ -2417,7 +2454,9 @@ static int mlx4_en_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
+@@ -2417,7 +2466,9 @@ static int mlx4_en_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
return mlx4_set_vf_rate(mdev->dev, en_priv->port, vf, min_tx_rate,
max_tx_rate);
}
static int mlx4_en_set_vf_spoofchk(struct net_device *dev, int vf, bool setting)
{
struct mlx4_en_priv *en_priv = netdev_priv(dev);
-@@ -2425,7 +2464,9 @@ static int mlx4_en_set_vf_spoofchk(struct net_device *dev, int vf, bool setting)
+@@ -2425,7 +2476,9 @@ static int mlx4_en_set_vf_spoofchk(struct net_device *dev, int vf, bool setting)
return mlx4_set_vf_spoofchk(mdev->dev, en_priv->port, vf, setting);
}
static int mlx4_en_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivf)
{
struct mlx4_en_priv *en_priv = netdev_priv(dev);
-@@ -2433,7 +2474,9 @@ static int mlx4_en_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_
+@@ -2433,7 +2486,9 @@ static int mlx4_en_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_
return mlx4_get_vf_config(mdev->dev, en_priv->port, vf, ivf);
}
static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_state)
{
struct mlx4_en_priv *en_priv = netdev_priv(dev);
-@@ -2441,7 +2484,9 @@ static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_st
+@@ -2441,7 +2496,9 @@ static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_st
return mlx4_set_vf_link_state(mdev->dev, en_priv->port, vf, link_state);
}
static int mlx4_en_get_vf_stats(struct net_device *dev, int vf,
struct ifla_vf_stats *vf_stats)
{
-@@ -2450,10 +2495,16 @@ static int mlx4_en_get_vf_stats(struct net_device *dev, int vf,
+@@ -2450,10 +2507,16 @@ static int mlx4_en_get_vf_stats(struct net_device *dev, int vf,
return mlx4_get_vf_stats(mdev->dev, en_priv->port, vf, vf_stats);
}
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_dev *mdev = priv->mdev->dev;
-@@ -2470,7 +2521,9 @@ static int mlx4_en_get_phys_port_id(struct net_device *dev,
+@@ -2470,7 +2533,9 @@ static int mlx4_en_get_phys_port_id(struct net_device *dev,
}
return 0;
}
static void mlx4_en_add_vxlan_offloads(struct work_struct *work)
{
int ret;
-@@ -2490,12 +2543,20 @@ out:
+@@ -2490,12 +2555,20 @@ out:
}
/* set offloads */
}
static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
-@@ -2504,12 +2565,20 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
+@@ -2504,12 +2577,20 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
vxlan_del_task);
/* unset offloads */
ret = mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port,
VXLAN_STEER_BY_OUTER_MAC, 0);
-@@ -2519,6 +2588,7 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
+@@ -2519,6 +2600,7 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
priv->vxlan_port = 0;
}
static void mlx4_en_add_vxlan_port(struct net_device *dev,
struct udp_tunnel_info *ti)
{
-@@ -2570,7 +2640,53 @@ static void mlx4_en_del_vxlan_port(struct net_device *dev,
+@@ -2570,7 +2652,53 @@ static void mlx4_en_del_vxlan_port(struct net_device *dev,
queue_work(priv->mdev->workqueue, &priv->vxlan_del_task);
}
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ __be16 current_port;
-
++
+ if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN)
+ return;
+
+ queue_work(priv->mdev->workqueue, &priv->vxlan_del_task);
+}
+#endif
-+
+
+#ifdef HAVE_NETDEV_FEATURES_T
static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
-@@ -2594,7 +2710,9 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
+@@ -2594,7 +2722,9 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
return features;
}
static int mlx4_en_set_tx_maxrate(struct net_device *dev, int queue_index, u32 maxrate)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
-@@ -2621,7 +2739,10 @@ static int mlx4_en_set_tx_maxrate(struct net_device *dev, int queue_index, u32 m
+@@ -2621,7 +2751,10 @@ static int mlx4_en_set_tx_maxrate(struct net_device *dev, int queue_index, u32 m
¶ms);
return err;
}
static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
-@@ -2718,6 +2839,7 @@ static int mlx4_xdp(struct net_device *dev, struct netdev_xdp *xdp)
+@@ -2718,6 +2851,7 @@ static int mlx4_xdp(struct net_device *dev, struct netdev_xdp *xdp)
return -EINVAL;
}
}
static const struct net_device_ops mlx4_netdev_ops = {
.ndo_open = mlx4_en_open,
-@@ -2738,16 +2860,35 @@ static const struct net_device_ops mlx4_netdev_ops = {
+@@ -2738,16 +2872,35 @@ static const struct net_device_ops mlx4_netdev_ops = {
#endif
.ndo_set_features = mlx4_en_set_features,
.ndo_fix_features = mlx4_en_fix_features,
};
static const struct net_device_ops mlx4_netdev_ops_master = {
-@@ -2765,27 +2906,79 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
+@@ -2764,28 +2917,84 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
+ .ndo_vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid,
.ndo_set_vf_mac = mlx4_en_set_vf_mac,
++#if defined(HAVE_NDO_SET_VF_VLAN)
.ndo_set_vf_vlan = mlx4_en_set_vf_vlan,
++#elif defined(HAVE_NDO_SET_VF_VLAN_EXTENDED)
++ .extended.ndo_set_vf_vlan = mlx4_en_set_vf_vlan,
++#endif
+#ifdef HAVE_TX_RATE_LIMIT
.ndo_set_vf_rate = mlx4_en_set_vf_rate,
+#endif
struct mlx4_en_bond {
struct work_struct work;
-@@ -2794,6 +2987,7 @@ struct mlx4_en_bond {
+@@ -2794,6 +3003,7 @@ struct mlx4_en_bond {
struct mlx4_port_map port_map;
};
static void mlx4_en_bond_work(struct work_struct *work)
{
struct mlx4_en_bond *bond = container_of(work,
-@@ -2960,6 +3154,7 @@ int mlx4_en_netdev_event(struct notifier_block *this,
+@@ -2960,6 +3170,7 @@ int mlx4_en_netdev_event(struct notifier_block *this,
return NOTIFY_DONE;
}
void mlx4_en_update_pfc_stats_bitmap(struct mlx4_dev *dev,
struct mlx4_en_stats_bitmap *stats_bitmap,
-@@ -3050,16 +3245,31 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3050,16 +3261,31 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
int i;
int err;
/*
* Initialize driver private data
-@@ -3074,8 +3284,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3074,8 +3300,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);
INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task);
#ifdef CONFIG_RFS_ACCEL
INIT_LIST_HEAD(&priv->filters);
spin_lock_init(&priv->filters_lock);
-@@ -3094,7 +3306,9 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3094,7 +3322,9 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
priv->num_tx_rings_p_up = mdev->profile.num_tx_rings_p_up;
priv->tx_ring_num = prof->tx_ring_num;
priv->tx_work_limit = MLX4_EN_DEFAULT_TX_WORK;
priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring *) * MAX_TX_RINGS,
GFP_KERNEL);
-@@ -3189,7 +3403,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3189,7 +3419,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
else
dev->netdev_ops = &mlx4_netdev_ops;
dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
dev->ethtool_ops = &mlx4_en_ethtool_ops;
-@@ -3245,6 +3463,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3245,6 +3479,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
if (mdev->dev->caps.steering_mode != MLX4_STEERING_MODE_A0)
dev->priv_flags |= IFF_UNICAST_FLT;
/* Setting a default hash function value */
if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_TOP) {
priv->rss_hash_fn = ETH_RSS_HASH_TOP;
-@@ -3255,8 +3474,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3255,8 +3490,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
"No RSS hash capabilities exposed, using Toeplitz\n");
priv->rss_hash_fn = ETH_RSS_HASH_TOP;
}
dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL;
-@@ -3264,6 +3485,12 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3264,6 +3501,12 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL;
dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
}
mdev->pndev[port] = dev;
-@@ -3327,8 +3554,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+@@ -3327,8 +3570,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
}
priv->registered = 1;