net/mlx5e: Add support for SR-IOV ndos
authorSaeed Mahameed <saeedm@mellanox.com>
Tue, 1 Dec 2015 16:03:25 +0000 (18:03 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 3 Dec 2015 17:08:47 +0000 (12:08 -0500)
Implement and enable SR-IOV ndos to manage SR-IOV configuration via
netdev netlink API.

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx5/core/en_main.c

index 007e464b3e585455bcf7ceaa031e3998fe46e8cc..d67058afe87ec96be19db7f43d6b3bb22006e7a6 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/mlx5/flow_table.h>
 #include "en.h"
+#include "eswitch.h"
 
 struct mlx5e_rq_param {
        u32                        rqc[MLX5_ST_SZ_DW(rqc)];
@@ -1931,6 +1932,79 @@ static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu)
        return err;
 }
 
+static int mlx5e_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+       struct mlx5_core_dev *mdev = priv->mdev;
+
+       return mlx5_eswitch_set_vport_mac(mdev->priv.eswitch, vf + 1, mac);
+}
+
+static int mlx5e_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+       struct mlx5_core_dev *mdev = priv->mdev;
+
+       return mlx5_eswitch_set_vport_vlan(mdev->priv.eswitch, vf + 1,
+                                          vlan, qos);
+}
+
+static int mlx5_vport_link2ifla(u8 esw_link)
+{
+       switch (esw_link) {
+       case MLX5_ESW_VPORT_ADMIN_STATE_DOWN:
+               return IFLA_VF_LINK_STATE_DISABLE;
+       case MLX5_ESW_VPORT_ADMIN_STATE_UP:
+               return IFLA_VF_LINK_STATE_ENABLE;
+       }
+       return IFLA_VF_LINK_STATE_AUTO;
+}
+
+static int mlx5_ifla_link2vport(u8 ifla_link)
+{
+       switch (ifla_link) {
+       case IFLA_VF_LINK_STATE_DISABLE:
+               return MLX5_ESW_VPORT_ADMIN_STATE_DOWN;
+       case IFLA_VF_LINK_STATE_ENABLE:
+               return MLX5_ESW_VPORT_ADMIN_STATE_UP;
+       }
+       return MLX5_ESW_VPORT_ADMIN_STATE_AUTO;
+}
+
+static int mlx5e_set_vf_link_state(struct net_device *dev, int vf,
+                                  int link_state)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+       struct mlx5_core_dev *mdev = priv->mdev;
+
+       return mlx5_eswitch_set_vport_state(mdev->priv.eswitch, vf + 1,
+                                           mlx5_ifla_link2vport(link_state));
+}
+
+static int mlx5e_get_vf_config(struct net_device *dev,
+                              int vf, struct ifla_vf_info *ivi)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+       struct mlx5_core_dev *mdev = priv->mdev;
+       int err;
+
+       err = mlx5_eswitch_get_vport_config(mdev->priv.eswitch, vf + 1, ivi);
+       if (err)
+               return err;
+       ivi->linkstate = mlx5_vport_link2ifla(ivi->linkstate);
+       return 0;
+}
+
+static int mlx5e_get_vf_stats(struct net_device *dev,
+                             int vf, struct ifla_vf_stats *vf_stats)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+       struct mlx5_core_dev *mdev = priv->mdev;
+
+       return mlx5_eswitch_get_vport_stats(mdev->priv.eswitch, vf + 1,
+                                           vf_stats);
+}
+
 static struct net_device_ops mlx5e_netdev_ops = {
        .ndo_open                = mlx5e_open,
        .ndo_stop                = mlx5e_close,
@@ -1941,7 +2015,7 @@ static struct net_device_ops mlx5e_netdev_ops = {
        .ndo_vlan_rx_add_vid     = mlx5e_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid    = mlx5e_vlan_rx_kill_vid,
        .ndo_set_features        = mlx5e_set_features,
-       .ndo_change_mtu          = mlx5e_change_mtu,
+       .ndo_change_mtu          = mlx5e_change_mtu
 };
 
 static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
@@ -2041,6 +2115,14 @@ static void mlx5e_build_netdev(struct net_device *netdev)
        if (priv->params.num_tc > 1)
                mlx5e_netdev_ops.ndo_select_queue = mlx5e_select_queue;
 
+       if (MLX5_CAP_GEN(mdev, vport_group_manager)) {
+               mlx5e_netdev_ops.ndo_set_vf_mac = mlx5e_set_vf_mac;
+               mlx5e_netdev_ops.ndo_set_vf_vlan = mlx5e_set_vf_vlan;
+               mlx5e_netdev_ops.ndo_get_vf_config = mlx5e_get_vf_config;
+               mlx5e_netdev_ops.ndo_set_vf_link_state = mlx5e_set_vf_link_state;
+               mlx5e_netdev_ops.ndo_get_vf_stats = mlx5e_get_vf_stats;
+       }
+
        netdev->netdev_ops        = &mlx5e_netdev_ops;
        netdev->watchdog_timeo    = 15 * HZ;