net/mlx5e: Add vnic devlink health reporter to representors
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_rep.c
index 8ff654b4e9e14101a5e0e65e0e6a32e22c48431a..2d87068f63fd5dd3216282dbf9157ddbb7760dc7 100644 (file)
@@ -53,6 +53,7 @@
 #include "lib/vxlan.h"
 #define CREATE_TRACE_POINTS
 #include "diag/en_rep_tracepoint.h"
+#include "diag/reporter_vnic.h"
 #include "en_accel/ipsec.h"
 #include "en/tc/int_port.h"
 #include "en/ptp.h"
@@ -1294,6 +1295,50 @@ static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv)
        return ARRAY_SIZE(mlx5e_ul_rep_stats_grps);
 }
 
+static int
+mlx5e_rep_vnic_reporter_diagnose(struct devlink_health_reporter *reporter,
+                                struct devlink_fmsg *fmsg,
+                                struct netlink_ext_ack *extack)
+{
+       struct mlx5e_rep_priv *rpriv = devlink_health_reporter_priv(reporter);
+       struct mlx5_eswitch_rep *rep = rpriv->rep;
+
+       return mlx5_reporter_vnic_diagnose_counters(rep->esw->dev, fmsg,
+                                                   rep->vport, true);
+}
+
+static const struct devlink_health_reporter_ops mlx5_rep_vnic_reporter_ops = {
+       .name = "vnic",
+       .diagnose = mlx5e_rep_vnic_reporter_diagnose,
+};
+
+static void mlx5e_rep_vnic_reporter_create(struct mlx5e_priv *priv,
+                                          struct devlink_port *dl_port)
+{
+       struct mlx5e_rep_priv *rpriv = priv->ppriv;
+       struct devlink_health_reporter *reporter;
+
+       reporter = devl_port_health_reporter_create(dl_port,
+                                                   &mlx5_rep_vnic_reporter_ops,
+                                                   0, rpriv);
+       if (IS_ERR(reporter)) {
+               mlx5_core_err(priv->mdev,
+                             "Failed to create representor vnic reporter, err = %ld\n",
+                             PTR_ERR(reporter));
+               return;
+       }
+
+       rpriv->rep_vnic_reporter = reporter;
+}
+
+static void mlx5e_rep_vnic_reporter_destroy(struct mlx5e_priv *priv)
+{
+       struct mlx5e_rep_priv *rpriv = priv->ppriv;
+
+       if (!IS_ERR_OR_NULL(rpriv->rep_vnic_reporter))
+               devl_health_reporter_destroy(rpriv->rep_vnic_reporter);
+}
+
 static const struct mlx5e_profile mlx5e_rep_profile = {
        .init                   = mlx5e_init_rep,
        .cleanup                = mlx5e_cleanup_rep,
@@ -1394,8 +1439,10 @@ mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
 
        dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch,
                                                 rpriv->rep->vport);
-       if (dl_port)
+       if (dl_port) {
                SET_NETDEV_DEVLINK_PORT(netdev, dl_port);
+               mlx5e_rep_vnic_reporter_create(priv, dl_port);
+       }
 
        err = register_netdev(netdev);
        if (err) {
@@ -1408,8 +1455,8 @@ mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
        return 0;
 
 err_detach_netdev:
+       mlx5e_rep_vnic_reporter_destroy(priv);
        mlx5e_detach_netdev(netdev_priv(netdev));
-
 err_cleanup_profile:
        priv->profile->cleanup(priv);
 
@@ -1458,6 +1505,7 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
        }
 
        unregister_netdev(netdev);
+       mlx5e_rep_vnic_reporter_destroy(priv);
        mlx5e_detach_netdev(priv);
        priv->profile->cleanup(priv);
        mlx5e_destroy_netdev(priv);