All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 net-next 00/11] qed: introduce devlink health support
@ 2020-07-29 11:38 Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 01/11] qed: move out devlink logic into a new file Igor Russkikh
                   ` (10 more replies)
  0 siblings, 11 replies; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh

This is a followup implementation after series

https://patchwork.ozlabs.org/project/netdev/cover/20200514095727.1361-1-irusskikh@marvell.com/

This is an implementation of devlink health infrastructure.

With this we are now able to report HW errors to devlink, and it'll take
its own actions depending on user configuration to capture and store the
dump at the bad moment, and to request the driver to recover the device.

So far we do not differentiate global device failures or specific PCI
function failures. This means that some errors specific to one physical
function will affect an entire device. This is not yet fully designed
and verified, will followup in future.

Solution was verified with artificial HW errors generated, existing
tools for dump analysis could be used.

v3: fix uninit var usage in patch 11
v2: fix #include issue from kbuild test robot.

Igor Russkikh (11):
  qed: move out devlink logic into a new file
  qed/qede: make devlink survive recovery
  qed: swap param init and publish
  qed: fix kconfig help entries
  qed: implement devlink info request
  qed: health reporter init deinit seq
  qed: use devlink logic to report errors
  qed*: make use of devlink recovery infrastructure
  qed: implement devlink dump
  qed: align adjacent indent
  qede: make driver reliable on unload after failures

 drivers/net/ethernet/qlogic/Kconfig           |   5 +-
 drivers/net/ethernet/qlogic/qed/Makefile      |   1 +
 drivers/net/ethernet/qlogic/qed/qed.h         |   3 +-
 drivers/net/ethernet/qlogic/qed/qed_dev.c     |  10 +
 drivers/net/ethernet/qlogic/qed/qed_devlink.c | 256 ++++++++++++++++++
 drivers/net/ethernet/qlogic/qed/qed_devlink.h |  20 ++
 drivers/net/ethernet/qlogic/qed/qed_main.c    | 116 +-------
 drivers/net/ethernet/qlogic/qede/qede.h       |   2 +
 drivers/net/ethernet/qlogic/qede/qede_main.c  |  39 ++-
 include/linux/qed/qed_if.h                    |  23 +-
 10 files changed, 345 insertions(+), 130 deletions(-)
 create mode 100644 drivers/net/ethernet/qlogic/qed/qed_devlink.c
 create mode 100644 drivers/net/ethernet/qlogic/qed/qed_devlink.h

-- 
2.17.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 01/11] qed: move out devlink logic into a new file
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 02/11] qed/qede: make devlink survive recovery Igor Russkikh
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

We are extending devlink infrastructure, thus move the existing
stuff into a new file qed_devlink.c

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 drivers/net/ethernet/qlogic/qed/Makefile      |   1 +
 drivers/net/ethernet/qlogic/qed/qed_devlink.c | 110 ++++++++++++++++++
 drivers/net/ethernet/qlogic/qed/qed_devlink.h |  15 +++
 drivers/net/ethernet/qlogic/qed/qed_main.c    | 102 +---------------
 4 files changed, 127 insertions(+), 101 deletions(-)
 create mode 100644 drivers/net/ethernet/qlogic/qed/qed_devlink.c
 create mode 100644 drivers/net/ethernet/qlogic/qed/qed_devlink.h

diff --git a/drivers/net/ethernet/qlogic/qed/Makefile b/drivers/net/ethernet/qlogic/qed/Makefile
index f947b105cf14..8251755ec18c 100644
--- a/drivers/net/ethernet/qlogic/qed/Makefile
+++ b/drivers/net/ethernet/qlogic/qed/Makefile
@@ -9,6 +9,7 @@ qed-y :=			\
 	qed_dcbx.o		\
 	qed_debug.o		\
 	qed_dev.o		\
+	qed_devlink.o		\
 	qed_hw.o		\
 	qed_init_fw_funcs.o	\
 	qed_init_ops.o		\
diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
new file mode 100644
index 000000000000..eb693787c99e
--- /dev/null
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Marvell/Qlogic FastLinQ NIC driver
+ *
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include <linux/kernel.h>
+#include "qed.h"
+#include "qed_devlink.h"
+
+enum qed_devlink_param_id {
+	QED_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
+	QED_DEVLINK_PARAM_ID_IWARP_CMT,
+};
+
+struct qed_devlink {
+	struct qed_dev *cdev;
+};
+
+static int qed_dl_param_get(struct devlink *dl, u32 id,
+			    struct devlink_param_gset_ctx *ctx)
+{
+	struct qed_devlink *qed_dl;
+	struct qed_dev *cdev;
+
+	qed_dl = devlink_priv(dl);
+	cdev = qed_dl->cdev;
+	ctx->val.vbool = cdev->iwarp_cmt;
+
+	return 0;
+}
+
+static int qed_dl_param_set(struct devlink *dl, u32 id,
+			    struct devlink_param_gset_ctx *ctx)
+{
+	struct qed_devlink *qed_dl;
+	struct qed_dev *cdev;
+
+	qed_dl = devlink_priv(dl);
+	cdev = qed_dl->cdev;
+	cdev->iwarp_cmt = ctx->val.vbool;
+
+	return 0;
+}
+
+static const struct devlink_param qed_devlink_params[] = {
+	DEVLINK_PARAM_DRIVER(QED_DEVLINK_PARAM_ID_IWARP_CMT,
+			     "iwarp_cmt", DEVLINK_PARAM_TYPE_BOOL,
+			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+			     qed_dl_param_get, qed_dl_param_set, NULL),
+};
+
+static const struct devlink_ops qed_dl_ops;
+
+int qed_devlink_register(struct qed_dev *cdev)
+{
+	union devlink_param_value value;
+	struct qed_devlink *qed_dl;
+	struct devlink *dl;
+	int rc;
+
+	dl = devlink_alloc(&qed_dl_ops, sizeof(*qed_dl));
+	if (!dl)
+		return -ENOMEM;
+
+	qed_dl = devlink_priv(dl);
+
+	cdev->dl = dl;
+	qed_dl->cdev = cdev;
+
+	rc = devlink_register(dl, &cdev->pdev->dev);
+	if (rc)
+		goto err_free;
+
+	rc = devlink_params_register(dl, qed_devlink_params,
+				     ARRAY_SIZE(qed_devlink_params));
+	if (rc)
+		goto err_unregister;
+
+	value.vbool = false;
+	devlink_param_driverinit_value_set(dl,
+					   QED_DEVLINK_PARAM_ID_IWARP_CMT,
+					   value);
+
+	devlink_params_publish(dl);
+	cdev->iwarp_cmt = false;
+
+	return 0;
+
+err_unregister:
+	devlink_unregister(dl);
+
+err_free:
+	cdev->dl = NULL;
+	devlink_free(dl);
+
+	return rc;
+}
+
+void qed_devlink_unregister(struct qed_dev *cdev)
+{
+	if (!cdev->dl)
+		return;
+
+	devlink_params_unregister(cdev->dl, qed_devlink_params,
+				  ARRAY_SIZE(qed_devlink_params));
+
+	devlink_unregister(cdev->dl);
+	devlink_free(cdev->dl);
+}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.h b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
new file mode 100644
index 000000000000..b94c40e9b7c1
--- /dev/null
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Marvell/Qlogic FastLinQ NIC driver
+ *
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+#ifndef _QED_DEVLINK_H
+#define _QED_DEVLINK_H
+
+#include <linux/qed/qed_if.h>
+#include <net/devlink.h>
+
+int qed_devlink_register(struct qed_dev *cdev);
+void qed_devlink_unregister(struct qed_dev *cdev);
+
+#endif
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 2558cb680db3..8751355d9ef7 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -39,6 +39,7 @@
 #include "qed_hw.h"
 #include "qed_selftest.h"
 #include "qed_debug.h"
+#include "qed_devlink.h"
 
 #define QED_ROCE_QPS			(8192)
 #define QED_ROCE_DPIS			(8)
@@ -510,107 +511,6 @@ static int qed_set_power_state(struct qed_dev *cdev, pci_power_t state)
 	return 0;
 }
 
-struct qed_devlink {
-	struct qed_dev *cdev;
-};
-
-enum qed_devlink_param_id {
-	QED_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
-	QED_DEVLINK_PARAM_ID_IWARP_CMT,
-};
-
-static int qed_dl_param_get(struct devlink *dl, u32 id,
-			    struct devlink_param_gset_ctx *ctx)
-{
-	struct qed_devlink *qed_dl;
-	struct qed_dev *cdev;
-
-	qed_dl = devlink_priv(dl);
-	cdev = qed_dl->cdev;
-	ctx->val.vbool = cdev->iwarp_cmt;
-
-	return 0;
-}
-
-static int qed_dl_param_set(struct devlink *dl, u32 id,
-			    struct devlink_param_gset_ctx *ctx)
-{
-	struct qed_devlink *qed_dl;
-	struct qed_dev *cdev;
-
-	qed_dl = devlink_priv(dl);
-	cdev = qed_dl->cdev;
-	cdev->iwarp_cmt = ctx->val.vbool;
-
-	return 0;
-}
-
-static const struct devlink_param qed_devlink_params[] = {
-	DEVLINK_PARAM_DRIVER(QED_DEVLINK_PARAM_ID_IWARP_CMT,
-			     "iwarp_cmt", DEVLINK_PARAM_TYPE_BOOL,
-			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
-			     qed_dl_param_get, qed_dl_param_set, NULL),
-};
-
-static const struct devlink_ops qed_dl_ops;
-
-static int qed_devlink_register(struct qed_dev *cdev)
-{
-	union devlink_param_value value;
-	struct qed_devlink *qed_dl;
-	struct devlink *dl;
-	int rc;
-
-	dl = devlink_alloc(&qed_dl_ops, sizeof(*qed_dl));
-	if (!dl)
-		return -ENOMEM;
-
-	qed_dl = devlink_priv(dl);
-
-	cdev->dl = dl;
-	qed_dl->cdev = cdev;
-
-	rc = devlink_register(dl, &cdev->pdev->dev);
-	if (rc)
-		goto err_free;
-
-	rc = devlink_params_register(dl, qed_devlink_params,
-				     ARRAY_SIZE(qed_devlink_params));
-	if (rc)
-		goto err_unregister;
-
-	value.vbool = false;
-	devlink_param_driverinit_value_set(dl,
-					   QED_DEVLINK_PARAM_ID_IWARP_CMT,
-					   value);
-
-	devlink_params_publish(dl);
-	cdev->iwarp_cmt = false;
-
-	return 0;
-
-err_unregister:
-	devlink_unregister(dl);
-
-err_free:
-	cdev->dl = NULL;
-	devlink_free(dl);
-
-	return rc;
-}
-
-static void qed_devlink_unregister(struct qed_dev *cdev)
-{
-	if (!cdev->dl)
-		return;
-
-	devlink_params_unregister(cdev->dl, qed_devlink_params,
-				  ARRAY_SIZE(qed_devlink_params));
-
-	devlink_unregister(cdev->dl);
-	devlink_free(cdev->dl);
-}
-
 /* probing */
 static struct qed_dev *qed_probe(struct pci_dev *pdev,
 				 struct qed_probe_params *params)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 02/11] qed/qede: make devlink survive recovery
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 01/11] qed: move out devlink logic into a new file Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  2020-07-29 12:49   ` Jiri Pirko
  2020-07-29 11:38 ` [PATCH v3 net-next 03/11] qed: swap param init and publish Igor Russkikh
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

Before that, devlink instance lifecycle was linked to qed_dev object,
that causes devlink to be recreated on each recovery.

Changing it by making higher level driver (qede) responsible for its
life. This way devlink will survive recoveries.

qede will store devlink structure pointer as a part of its device
object, devlink private data contains a linkage structure, it'll
contain extra devlink related content in following patches.

The same lifecycle should be applied to storage drivers (qedf/qedi) later.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 drivers/net/ethernet/qlogic/qed/qed.h         |  1 -
 drivers/net/ethernet/qlogic/qed/qed_devlink.c | 40 ++++++++-----------
 drivers/net/ethernet/qlogic/qed/qed_devlink.h |  4 +-
 drivers/net/ethernet/qlogic/qed/qed_main.c    | 10 +----
 drivers/net/ethernet/qlogic/qede/qede.h       |  1 +
 drivers/net/ethernet/qlogic/qede/qede_main.c  | 18 +++++++++
 include/linux/qed/qed_if.h                    |  9 +++++
 7 files changed, 48 insertions(+), 35 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index b2a7b53ee760..b6ce1488abcc 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -849,7 +849,6 @@ struct qed_dev {
 	u32 rdma_max_srq_sge;
 	u16 tunn_feature_mask;
 
-	struct devlink			*dl;
 	bool				iwarp_cmt;
 };
 
diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
index eb693787c99e..a62c47c61edf 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/qed/qed_if.h>
 #include "qed.h"
 #include "qed_devlink.h"
 
@@ -13,17 +14,12 @@ enum qed_devlink_param_id {
 	QED_DEVLINK_PARAM_ID_IWARP_CMT,
 };
 
-struct qed_devlink {
-	struct qed_dev *cdev;
-};
-
 static int qed_dl_param_get(struct devlink *dl, u32 id,
 			    struct devlink_param_gset_ctx *ctx)
 {
-	struct qed_devlink *qed_dl;
+	struct qed_devlink *qed_dl = devlink_priv(dl);
 	struct qed_dev *cdev;
 
-	qed_dl = devlink_priv(dl);
 	cdev = qed_dl->cdev;
 	ctx->val.vbool = cdev->iwarp_cmt;
 
@@ -33,10 +29,9 @@ static int qed_dl_param_get(struct devlink *dl, u32 id,
 static int qed_dl_param_set(struct devlink *dl, u32 id,
 			    struct devlink_param_gset_ctx *ctx)
 {
-	struct qed_devlink *qed_dl;
+	struct qed_devlink *qed_dl = devlink_priv(dl);
 	struct qed_dev *cdev;
 
-	qed_dl = devlink_priv(dl);
 	cdev = qed_dl->cdev;
 	cdev->iwarp_cmt = ctx->val.vbool;
 
@@ -52,21 +47,19 @@ static const struct devlink_param qed_devlink_params[] = {
 
 static const struct devlink_ops qed_dl_ops;
 
-int qed_devlink_register(struct qed_dev *cdev)
+struct devlink *qed_devlink_register(struct qed_dev *cdev)
 {
 	union devlink_param_value value;
-	struct qed_devlink *qed_dl;
+	struct qed_devlink *qdevlink;
 	struct devlink *dl;
 	int rc;
 
-	dl = devlink_alloc(&qed_dl_ops, sizeof(*qed_dl));
+	dl = devlink_alloc(&qed_dl_ops, sizeof(struct qed_devlink));
 	if (!dl)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
-	qed_dl = devlink_priv(dl);
-
-	cdev->dl = dl;
-	qed_dl->cdev = cdev;
+	qdevlink = devlink_priv(dl);
+	qdevlink->cdev = cdev;
 
 	rc = devlink_register(dl, &cdev->pdev->dev);
 	if (rc)
@@ -85,26 +78,25 @@ int qed_devlink_register(struct qed_dev *cdev)
 	devlink_params_publish(dl);
 	cdev->iwarp_cmt = false;
 
-	return 0;
+	return dl;
 
 err_unregister:
 	devlink_unregister(dl);
 
 err_free:
-	cdev->dl = NULL;
 	devlink_free(dl);
 
-	return rc;
+	return ERR_PTR(rc);
 }
 
-void qed_devlink_unregister(struct qed_dev *cdev)
+void qed_devlink_unregister(struct devlink *devlink)
 {
-	if (!cdev->dl)
+	if (!devlink)
 		return;
 
-	devlink_params_unregister(cdev->dl, qed_devlink_params,
+	devlink_params_unregister(devlink, qed_devlink_params,
 				  ARRAY_SIZE(qed_devlink_params));
 
-	devlink_unregister(cdev->dl);
-	devlink_free(cdev->dl);
+	devlink_unregister(devlink);
+	devlink_free(devlink);
 }
diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.h b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
index b94c40e9b7c1..c79dc6bfa194 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
@@ -9,7 +9,7 @@
 #include <linux/qed/qed_if.h>
 #include <net/devlink.h>
 
-int qed_devlink_register(struct qed_dev *cdev);
-void qed_devlink_unregister(struct qed_dev *cdev);
+struct devlink *qed_devlink_register(struct qed_dev *cdev);
+void qed_devlink_unregister(struct devlink *devlink);
 
 #endif
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 8751355d9ef7..d6f76421379b 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -539,12 +539,6 @@ static struct qed_dev *qed_probe(struct pci_dev *pdev,
 	}
 	DP_INFO(cdev, "PCI init completed successfully\n");
 
-	rc = qed_devlink_register(cdev);
-	if (rc) {
-		DP_INFO(cdev, "Failed to register devlink.\n");
-		goto err2;
-	}
-
 	rc = qed_hw_prepare(cdev, QED_PCI_DEFAULT);
 	if (rc) {
 		DP_ERR(cdev, "hw prepare failed\n");
@@ -574,8 +568,6 @@ static void qed_remove(struct qed_dev *cdev)
 
 	qed_set_power_state(cdev, PCI_D3hot);
 
-	qed_devlink_unregister(cdev);
-
 	qed_free_cdev(cdev);
 }
 
@@ -3012,6 +3004,8 @@ const struct qed_common_ops qed_common_ops_pass = {
 	.get_link = &qed_get_current_link,
 	.drain = &qed_drain,
 	.update_msglvl = &qed_init_dp,
+	.devlink_register = qed_devlink_register,
+	.devlink_unregister = qed_devlink_unregister,
 	.dbg_all_data = &qed_dbg_all_data,
 	.dbg_all_data_size = &qed_dbg_all_data_size,
 	.chain_alloc = &qed_chain_alloc,
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index 803c1fcca8ad..1f0e7505a973 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -172,6 +172,7 @@ struct qede_dev {
 	struct qed_dev			*cdev;
 	struct net_device		*ndev;
 	struct pci_dev			*pdev;
+	struct devlink			*devlink;
 
 	u32				dp_module;
 	u8				dp_level;
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 1aaae3203f5a..7c2d948b2035 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -1172,10 +1172,23 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
 			rc = -ENOMEM;
 			goto err2;
 		}
+
+		edev->devlink = qed_ops->common->devlink_register(cdev);
+		if (IS_ERR(edev->devlink)) {
+			DP_NOTICE(edev, "Cannot register devlink\n");
+			edev->devlink = NULL;
+			/* Go on, we can live without devlink */
+		}
 	} else {
 		struct net_device *ndev = pci_get_drvdata(pdev);
 
 		edev = netdev_priv(ndev);
+
+		if (edev && edev->devlink) {
+			struct qed_devlink *qdl = devlink_priv(edev->devlink);
+
+			qdl->cdev = cdev;
+		}
 		edev->cdev = cdev;
 		memset(&edev->stats, 0, sizeof(edev->stats));
 		memcpy(&edev->dev_info, &dev_info, sizeof(dev_info));
@@ -1298,6 +1311,11 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
 	qed_ops->common->slowpath_stop(cdev);
 	if (system_state == SYSTEM_POWER_OFF)
 		return;
+
+	if (mode != QEDE_REMOVE_RECOVERY && edev->devlink) {
+		qed_ops->common->devlink_unregister(edev->devlink);
+		edev->devlink = NULL;
+	}
 	qed_ops->common->remove(cdev);
 	edev->cdev = NULL;
 
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index cd6a5c7e56eb..d8368e1770df 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -21,6 +21,7 @@
 #include <linux/qed/common_hsi.h>
 #include <linux/qed/qed_chain.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
+#include <net/devlink.h>
 
 enum dcbx_protocol_type {
 	DCBX_PROTOCOL_ISCSI,
@@ -779,6 +780,10 @@ enum qed_nvm_flash_cmd {
 	QED_NVM_FLASH_CMD_NVM_MAX,
 };
 
+struct qed_devlink {
+	struct qed_dev *cdev;
+};
+
 struct qed_common_cb_ops {
 	void (*arfs_filter_op)(void *dev, void *fltr, u8 fw_rc);
 	void (*link_update)(void *dev, struct qed_link_output *link);
@@ -1137,6 +1142,10 @@ struct qed_common_ops {
  *
  */
 	int (*set_grc_config)(struct qed_dev *cdev, u32 cfg_id, u32 val);
+
+	struct devlink* (*devlink_register)(struct qed_dev *cdev);
+
+	void (*devlink_unregister)(struct devlink *devlink);
 };
 
 #define MASK_FIELD(_name, _value) \
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 03/11] qed: swap param init and publish
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 01/11] qed: move out devlink logic into a new file Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 02/11] qed/qede: make devlink survive recovery Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  2020-07-29 12:51   ` Jiri Pirko
  2020-07-29 11:38 ` [PATCH v3 net-next 04/11] qed: fix kconfig help entries Igor Russkikh
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

In theory that could lead to race condition

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 drivers/net/ethernet/qlogic/qed/qed_devlink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
index a62c47c61edf..4e3316c6beb6 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -75,8 +75,8 @@ struct devlink *qed_devlink_register(struct qed_dev *cdev)
 					   QED_DEVLINK_PARAM_ID_IWARP_CMT,
 					   value);
 
-	devlink_params_publish(dl);
 	cdev->iwarp_cmt = false;
+	devlink_params_publish(dl);
 
 	return dl;
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 04/11] qed: fix kconfig help entries
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
                   ` (2 preceding siblings ...)
  2020-07-29 11:38 ` [PATCH v3 net-next 03/11] qed: swap param init and publish Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 05/11] qed: implement devlink info request Igor Russkikh
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

This patch replaces stubs in kconfig help entries with an actual description.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 drivers/net/ethernet/qlogic/Kconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig
index 8f743d80760b..4366c7a8de95 100644
--- a/drivers/net/ethernet/qlogic/Kconfig
+++ b/drivers/net/ethernet/qlogic/Kconfig
@@ -80,7 +80,7 @@ config QED
 	select CRC8
 	select NET_DEVLINK
 	help
-	  This enables the support for ...
+	  This enables the support for Marvell FastLinQ adapters family.
 
 config QED_LL2
 	bool
@@ -100,7 +100,8 @@ config QEDE
 	depends on QED
 	imply PTP_1588_CLOCK
 	help
-	  This enables the support for ...
+	  This enables the support for Marvell FastLinQ adapters family,
+	  ethernet driver.
 
 config QED_RDMA
 	bool
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 05/11] qed: implement devlink info request
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
                   ` (3 preceding siblings ...)
  2020-07-29 11:38 ` [PATCH v3 net-next 04/11] qed: fix kconfig help entries Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  2020-07-29 12:52   ` Jiri Pirko
  2020-07-29 11:38 ` [PATCH v3 net-next 06/11] qed: health reporter init deinit seq Igor Russkikh
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

Here we return existing fw & mfw versions, we also fetch device's
serial number.

The base device specific structure (qed_dev_info) was not directly
available to the base driver before.
Thus, here we create and store a private copy of this structure
in qed_dev root object.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 drivers/net/ethernet/qlogic/qed/qed.h         |  1 +
 drivers/net/ethernet/qlogic/qed/qed_dev.c     | 10 ++++
 drivers/net/ethernet/qlogic/qed/qed_devlink.c | 52 ++++++++++++++++++-
 drivers/net/ethernet/qlogic/qed/qed_main.c    |  1 +
 4 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index b6ce1488abcc..ccd789eeda3e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -807,6 +807,7 @@ struct qed_dev {
 	struct qed_llh_info *p_llh_info;
 
 	/* Linux specific here */
+	struct qed_dev_info		common_dev_info;
 	struct  qede_dev		*edev;
 	struct  pci_dev			*pdev;
 	u32 flags;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index b3c9ebaf2280..377950ce8ea2 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -4290,6 +4290,16 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 		__set_bit(QED_DEV_CAP_ROCE,
 			  &p_hwfn->hw_info.device_capabilities);
 
+	/* Read device serial number information from shmem */
+	addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
+		offsetof(struct nvm_cfg1, glob) +
+		offsetof(struct nvm_cfg1_glob, serial_number);
+
+	p_hwfn->hw_info.part_num[0] = qed_rd(p_hwfn, p_ptt, addr);
+	p_hwfn->hw_info.part_num[1] = qed_rd(p_hwfn, p_ptt, addr + 4);
+	p_hwfn->hw_info.part_num[2] = qed_rd(p_hwfn, p_ptt, addr + 8);
+	p_hwfn->hw_info.part_num[3] = qed_rd(p_hwfn, p_ptt, addr + 12);
+
 	return qed_mcp_fill_shmem_func_info(p_hwfn, p_ptt);
 }
 
diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
index 4e3316c6beb6..5bd5528dc409 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -45,7 +45,57 @@ static const struct devlink_param qed_devlink_params[] = {
 			     qed_dl_param_get, qed_dl_param_set, NULL),
 };
 
-static const struct devlink_ops qed_dl_ops;
+static int qed_devlink_info_get(struct devlink *devlink,
+				struct devlink_info_req *req,
+				struct netlink_ext_ack *extack)
+{
+	struct qed_devlink *qed_dl = devlink_priv(devlink);
+	struct qed_dev *cdev = qed_dl->cdev;
+	struct qed_dev_info *dev_info;
+	char buf[100];
+	int err;
+
+	dev_info = &cdev->common_dev_info;
+
+	err = devlink_info_driver_name_put(req, KBUILD_MODNAME);
+	if (err)
+		return err;
+
+	memcpy(buf, cdev->hwfns[0].hw_info.part_num, sizeof(cdev->hwfns[0].hw_info.part_num));
+	buf[sizeof(cdev->hwfns[0].hw_info.part_num)] = 0;
+
+	if (buf[0]) {
+		err = devlink_info_serial_number_put(req, buf);
+		if (err)
+			return err;
+	}
+
+	snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
+		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_3),
+		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_2),
+		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_1),
+		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_0));
+
+	err = devlink_info_version_stored_put(req,
+					      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, buf);
+	if (err)
+		return err;
+
+	snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
+		 dev_info->fw_major,
+		 dev_info->fw_minor,
+		 dev_info->fw_rev,
+		 dev_info->fw_eng);
+
+	err = devlink_info_version_running_put(req,
+					       DEVLINK_INFO_VERSION_GENERIC_FW, buf);
+
+	return err;
+}
+
+static const struct devlink_ops qed_dl_ops = {
+	.info_get = qed_devlink_info_get,
+};
 
 struct devlink *qed_devlink_register(struct qed_dev *cdev)
 {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index d6f76421379b..d1a559ccf516 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -479,6 +479,7 @@ int qed_fill_dev_info(struct qed_dev *cdev,
 	}
 
 	dev_info->mtu = hw_info->mtu;
+	cdev->common_dev_info = *dev_info;
 
 	return 0;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 06/11] qed: health reporter init deinit seq
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
                   ` (4 preceding siblings ...)
  2020-07-29 11:38 ` [PATCH v3 net-next 05/11] qed: implement devlink info request Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 07/11] qed: use devlink logic to report errors Igor Russkikh
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

Here we declare health reporter ops (empty for now)
and register these in qed probe and remove callbacks.

This way we get devlink attached to all kind of qed* PCI
device entities: networking or storage offload entity.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 drivers/net/ethernet/qlogic/qed/qed_devlink.c | 30 +++++++++++++++++++
 drivers/net/ethernet/qlogic/qed/qed_devlink.h |  3 ++
 include/linux/qed/qed_if.h                    |  1 +
 3 files changed, 34 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
index 5bd5528dc409..843a35f14cca 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -14,6 +14,34 @@ enum qed_devlink_param_id {
 	QED_DEVLINK_PARAM_ID_IWARP_CMT,
 };
 
+static const struct devlink_health_reporter_ops qed_fw_fatal_reporter_ops = {
+		.name = "fw_fatal",
+};
+
+#define QED_REPORTER_FW_GRACEFUL_PERIOD 1200000
+
+void qed_fw_reporters_create(struct devlink *devlink)
+{
+	struct qed_devlink *dl = devlink_priv(devlink);
+
+	dl->fw_reporter = devlink_health_reporter_create(devlink, &qed_fw_fatal_reporter_ops,
+							 QED_REPORTER_FW_GRACEFUL_PERIOD, dl);
+	if (IS_ERR(dl->fw_reporter))
+		DP_NOTICE(dl->cdev, "Failed to create fw reporter, err = %ld\n",
+			  PTR_ERR(dl->fw_reporter));
+}
+
+void qed_fw_reporters_destroy(struct devlink *devlink)
+{
+	struct qed_devlink *dl = devlink_priv(devlink);
+	struct devlink_health_reporter *rep;
+
+	rep = dl->fw_reporter;
+
+	if (!IS_ERR_OR_NULL(rep))
+		devlink_health_reporter_destroy(rep);
+}
+
 static int qed_dl_param_get(struct devlink *dl, u32 id,
 			    struct devlink_param_gset_ctx *ctx)
 {
@@ -144,6 +172,8 @@ void qed_devlink_unregister(struct devlink *devlink)
 	if (!devlink)
 		return;
 
+	qed_fw_reporters_destroy(devlink);
+
 	devlink_params_unregister(devlink, qed_devlink_params,
 				  ARRAY_SIZE(qed_devlink_params));
 
diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.h b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
index c79dc6bfa194..c68ecf778826 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
@@ -12,4 +12,7 @@
 struct devlink *qed_devlink_register(struct qed_dev *cdev);
 void qed_devlink_unregister(struct devlink *devlink);
 
+void qed_fw_reporters_create(struct devlink *devlink);
+void qed_fw_reporters_destroy(struct devlink *devlink);
+
 #endif
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index d8368e1770df..30fe06fe06a0 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -782,6 +782,7 @@ enum qed_nvm_flash_cmd {
 
 struct qed_devlink {
 	struct qed_dev *cdev;
+	struct devlink_health_reporter *fw_reporter;
 };
 
 struct qed_common_cb_ops {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 07/11] qed: use devlink logic to report errors
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
                   ` (5 preceding siblings ...)
  2020-07-29 11:38 ` [PATCH v3 net-next 06/11] qed: health reporter init deinit seq Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  2020-07-29 13:08   ` Jiri Pirko
  2020-07-29 11:38 ` [PATCH v3 net-next 08/11] qed*: make use of devlink recovery infrastructure Igor Russkikh
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

Use devlink_health_report to push error indications.
We implement this in qede via callback function to make it possible
to reuse the same for other drivers sitting on top of qed in future.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 drivers/net/ethernet/qlogic/qed/qed_devlink.c | 17 +++++++++++++++++
 drivers/net/ethernet/qlogic/qed/qed_devlink.h |  2 ++
 drivers/net/ethernet/qlogic/qed/qed_main.c    |  1 +
 drivers/net/ethernet/qlogic/qede/qede.h       |  1 +
 drivers/net/ethernet/qlogic/qede/qede_main.c  |  5 ++++-
 include/linux/qed/qed_if.h                    |  3 +++
 6 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
index 843a35f14cca..ffe776a4f99a 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -14,6 +14,23 @@ enum qed_devlink_param_id {
 	QED_DEVLINK_PARAM_ID_IWARP_CMT,
 };
 
+struct qed_fw_fatal_ctx {
+	enum qed_hw_err_type err_type;
+};
+
+int qed_report_fatal_error(struct devlink *devlink, enum qed_hw_err_type err_type)
+{
+	struct qed_devlink *qdl = devlink_priv(devlink);
+	struct qed_fw_fatal_ctx fw_fatal_ctx = {
+		.err_type = err_type,
+	};
+
+	devlink_health_report(qdl->fw_reporter,
+			      "Fatal error reported", &fw_fatal_ctx);
+
+	return 0;
+}
+
 static const struct devlink_health_reporter_ops qed_fw_fatal_reporter_ops = {
 		.name = "fw_fatal",
 };
diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.h b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
index c68ecf778826..ccc7d1d1bfd4 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
@@ -15,4 +15,6 @@ void qed_devlink_unregister(struct devlink *devlink);
 void qed_fw_reporters_create(struct devlink *devlink);
 void qed_fw_reporters_destroy(struct devlink *devlink);
 
+int qed_report_fatal_error(struct devlink *dl, enum qed_hw_err_type err_type);
+
 #endif
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index d1a559ccf516..a64d594f9294 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -3007,6 +3007,7 @@ const struct qed_common_ops qed_common_ops_pass = {
 	.update_msglvl = &qed_init_dp,
 	.devlink_register = qed_devlink_register,
 	.devlink_unregister = qed_devlink_unregister,
+	.report_fatal_error = qed_report_fatal_error,
 	.dbg_all_data = &qed_dbg_all_data,
 	.dbg_all_data_size = &qed_dbg_all_data_size,
 	.chain_alloc = &qed_chain_alloc,
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index 1f0e7505a973..3efc5899f656 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -264,6 +264,7 @@ struct qede_dev {
 
 	struct bpf_prog			*xdp_prog;
 
+	enum qed_hw_err_type		last_err_type;
 	unsigned long			err_flags;
 #define QEDE_ERR_IS_HANDLED		31
 #define QEDE_ERR_ATTN_CLR_EN		0
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 7c2d948b2035..df437c3f1fc9 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -1181,7 +1181,6 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
 		}
 	} else {
 		struct net_device *ndev = pci_get_drvdata(pdev);
-
 		edev = netdev_priv(ndev);
 
 		if (edev && edev->devlink) {
@@ -2603,6 +2602,9 @@ static void qede_generic_hw_err_handler(struct qede_dev *edev)
 		  "Generic sleepable HW error handling started - err_flags 0x%lx\n",
 		  edev->err_flags);
 
+	if (edev->devlink)
+		edev->ops->common->report_fatal_error(edev->devlink, edev->last_err_type);
+
 	/* Trigger a recovery process.
 	 * This is placed in the sleep requiring section just to make
 	 * sure it is the last one, and that all the other operations
@@ -2663,6 +2665,7 @@ static void qede_schedule_hw_err_handler(void *dev,
 		return;
 	}
 
+	edev->last_err_type = err_type;
 	qede_set_hw_err_flags(edev, err_type);
 	qede_atomic_hw_err_handler(edev);
 	set_bit(QEDE_SP_HW_ERR, &edev->sp_flags);
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index 30fe06fe06a0..1297726f2b25 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -906,6 +906,9 @@ struct qed_common_ops {
 
 	int (*dbg_all_data_size) (struct qed_dev *cdev);
 
+	int		(*report_fatal_error)(struct devlink *devlink,
+					      enum qed_hw_err_type err_type);
+
 /**
  * @brief can_link_change - can the instance change the link or not
  *
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 08/11] qed*: make use of devlink recovery infrastructure
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
                   ` (6 preceding siblings ...)
  2020-07-29 11:38 ` [PATCH v3 net-next 07/11] qed: use devlink logic to report errors Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 09/11] qed: implement devlink dump Igor Russkikh
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

Remove forcible recovery trigger and put it as a normal devlink
callback.

This allows user to enable/disable it via

    devlink health set pci/0000:03:00.0 reporter fw_fatal auto_recover false

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 drivers/net/ethernet/qlogic/qed/qed.h         |  1 +
 drivers/net/ethernet/qlogic/qed/qed_devlink.c | 14 ++++++++++++++
 drivers/net/ethernet/qlogic/qed/qed_main.c    |  2 +-
 drivers/net/ethernet/qlogic/qede/qede_main.c  | 10 ----------
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index ccd789eeda3e..f34b25a79449 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -981,6 +981,7 @@ void qed_bw_update(struct qed_hwfn *hwfn, struct qed_ptt *ptt);
 u32 qed_unzip_data(struct qed_hwfn *p_hwfn,
 		   u32 input_len, u8 *input_buf,
 		   u32 max_size, u8 *unzip_buf);
+int qed_recovery_process(struct qed_dev *cdev);
 void qed_schedule_recovery_handler(struct qed_hwfn *p_hwfn);
 void qed_hw_error_occurred(struct qed_hwfn *p_hwfn,
 			   enum qed_hw_err_type err_type);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
index ffe776a4f99a..b25be68f959c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -31,8 +31,22 @@ int qed_report_fatal_error(struct devlink *devlink, enum qed_hw_err_type err_typ
 	return 0;
 }
 
+static int
+qed_fw_fatal_reporter_recover(struct devlink_health_reporter *reporter,
+			      void *priv_ctx,
+			      struct netlink_ext_ack *extack)
+{
+	struct qed_devlink *qdl = devlink_health_reporter_priv(reporter);
+	struct qed_dev *cdev = qdl->cdev;
+
+	qed_recovery_process(cdev);
+
+	return 0;
+}
+
 static const struct devlink_health_reporter_ops qed_fw_fatal_reporter_ops = {
 		.name = "fw_fatal",
+		.recover = qed_fw_fatal_reporter_recover,
 };
 
 #define QED_REPORTER_FW_GRACEFUL_PERIOD 1200000
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index a64d594f9294..db5d003770ba 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -2817,7 +2817,7 @@ static int qed_set_led(struct qed_dev *cdev, enum qed_led_mode mode)
 	return status;
 }
 
-static int qed_recovery_process(struct qed_dev *cdev)
+int qed_recovery_process(struct qed_dev *cdev)
 {
 	struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
 	struct qed_ptt *p_ptt;
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index df437c3f1fc9..937d8e69ad39 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -2596,8 +2596,6 @@ static void qede_atomic_hw_err_handler(struct qede_dev *edev)
 
 static void qede_generic_hw_err_handler(struct qede_dev *edev)
 {
-	struct qed_dev *cdev = edev->cdev;
-
 	DP_NOTICE(edev,
 		  "Generic sleepable HW error handling started - err_flags 0x%lx\n",
 		  edev->err_flags);
@@ -2605,14 +2603,6 @@ static void qede_generic_hw_err_handler(struct qede_dev *edev)
 	if (edev->devlink)
 		edev->ops->common->report_fatal_error(edev->devlink, edev->last_err_type);
 
-	/* Trigger a recovery process.
-	 * This is placed in the sleep requiring section just to make
-	 * sure it is the last one, and that all the other operations
-	 * were completed.
-	 */
-	if (test_bit(QEDE_ERR_IS_RECOVERABLE, &edev->err_flags))
-		edev->ops->common->recovery_process(cdev);
-
 	clear_bit(QEDE_ERR_IS_HANDLED, &edev->err_flags);
 
 	DP_NOTICE(edev, "Generic sleepable HW error handling is done\n");
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 09/11] qed: implement devlink dump
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
                   ` (7 preceding siblings ...)
  2020-07-29 11:38 ` [PATCH v3 net-next 08/11] qed*: make use of devlink recovery infrastructure Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 10/11] qed: align adjacent indent Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 11/11] qede: make driver reliable on unload after failures Igor Russkikh
  10 siblings, 0 replies; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

Gather and push out full device dump to devlink.
Device dump is the same as with `ethtool -d`, but now its generated
exactly at the moment bad thing happens.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 drivers/net/ethernet/qlogic/qed/qed_devlink.c | 43 +++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
index b25be68f959c..904babe70489 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -6,6 +6,7 @@
 
 #include <linux/kernel.h>
 #include <linux/qed/qed_if.h>
+#include <linux/vmalloc.h>
 #include "qed.h"
 #include "qed_devlink.h"
 
@@ -31,6 +32,47 @@ int qed_report_fatal_error(struct devlink *devlink, enum qed_hw_err_type err_typ
 	return 0;
 }
 
+static int
+qed_fw_fatal_reporter_dump(struct devlink_health_reporter *reporter,
+			   struct devlink_fmsg *fmsg, void *priv_ctx,
+			   struct netlink_ext_ack *extack)
+{
+	struct qed_devlink *qdl = devlink_health_reporter_priv(reporter);
+	struct qed_fw_fatal_ctx *fw_fatal_ctx = priv_ctx;
+	struct qed_dev *cdev = qdl->cdev;
+	u32 dbg_data_buf_size;
+	u8 *p_dbg_data_buf;
+	int err;
+
+	/* Having context means that was a dump request after fatal,
+	 * so we enable extra debugging while gathering the dump,
+	 * just in case
+	 */
+	cdev->print_dbg_data = fw_fatal_ctx ? true : false;
+
+	dbg_data_buf_size = qed_dbg_all_data_size(cdev);
+	p_dbg_data_buf = vzalloc(dbg_data_buf_size);
+	if (!p_dbg_data_buf) {
+		DP_NOTICE(cdev,
+			  "Failed to allocate memory for a debug data buffer\n");
+		return -ENOMEM;
+	}
+
+	err = qed_dbg_all_data(cdev, p_dbg_data_buf);
+	if (err) {
+		DP_NOTICE(cdev, "Failed to obtain debug data\n");
+		vfree(p_dbg_data_buf);
+		return err;
+	}
+
+	err = devlink_fmsg_binary_pair_put(fmsg, "dump_data",
+					   p_dbg_data_buf, dbg_data_buf_size);
+
+	vfree(p_dbg_data_buf);
+
+	return err;
+}
+
 static int
 qed_fw_fatal_reporter_recover(struct devlink_health_reporter *reporter,
 			      void *priv_ctx,
@@ -47,6 +89,7 @@ qed_fw_fatal_reporter_recover(struct devlink_health_reporter *reporter,
 static const struct devlink_health_reporter_ops qed_fw_fatal_reporter_ops = {
 		.name = "fw_fatal",
 		.recover = qed_fw_fatal_reporter_recover,
+		.dump = qed_fw_fatal_reporter_dump,
 };
 
 #define QED_REPORTER_FW_GRACEFUL_PERIOD 1200000
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 10/11] qed: align adjacent indent
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
                   ` (8 preceding siblings ...)
  2020-07-29 11:38 ` [PATCH v3 net-next 09/11] qed: implement devlink dump Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  2020-07-29 11:38 ` [PATCH v3 net-next 11/11] qede: make driver reliable on unload after failures Igor Russkikh
  10 siblings, 0 replies; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

Fix indent on some of adjacent declarations.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 include/linux/qed/qed_if.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index 1297726f2b25..b8fb80c9be80 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -897,14 +897,14 @@ struct qed_common_ops {
 
 	void		(*simd_handler_clean)(struct qed_dev *cdev,
 					      int index);
-	int (*dbg_grc)(struct qed_dev *cdev,
-		       void *buffer, u32 *num_dumped_bytes);
+	int		(*dbg_grc)(struct qed_dev *cdev,
+				   void *buffer, u32 *num_dumped_bytes);
 
-	int (*dbg_grc_size)(struct qed_dev *cdev);
+	int		(*dbg_grc_size)(struct qed_dev *cdev);
 
-	int (*dbg_all_data) (struct qed_dev *cdev, void *buffer);
+	int		(*dbg_all_data)(struct qed_dev *cdev, void *buffer);
 
-	int (*dbg_all_data_size) (struct qed_dev *cdev);
+	int		(*dbg_all_data_size)(struct qed_dev *cdev);
 
 	int		(*report_fatal_error)(struct devlink *devlink,
 					      enum qed_hw_err_type err_type);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 net-next 11/11] qede: make driver reliable on unload after failures
  2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
                   ` (9 preceding siblings ...)
  2020-07-29 11:38 ` [PATCH v3 net-next 10/11] qed: align adjacent indent Igor Russkikh
@ 2020-07-29 11:38 ` Igor Russkikh
  10 siblings, 0 replies; 17+ messages in thread
From: Igor Russkikh @ 2020-07-29 11:38 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
	Alexander Lobakin, Igor Russkikh, Michal Kalderon

In case recovery was not successful, netdev still should be
present. But we should clear cdev if something bad happens
on recovery.

We also check cdev for null on dev close. That could be a case
if recovery was not successful.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
---
 drivers/net/ethernet/qlogic/qede/qede_main.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 937d8e69ad39..eeb4a7311633 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -1239,7 +1239,10 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
 err4:
 	qede_rdma_dev_remove(edev, (mode == QEDE_PROBE_RECOVERY));
 err3:
-	free_netdev(edev->ndev);
+	if (mode != QEDE_PROBE_RECOVERY)
+		free_netdev(edev->ndev);
+	else
+		edev->cdev = NULL;
 err2:
 	qed_ops->common->slowpath_stop(cdev);
 err1:
@@ -2474,7 +2477,8 @@ static int qede_close(struct net_device *ndev)
 
 	qede_unload(edev, QEDE_UNLOAD_NORMAL, false);
 
-	edev->ops->common->update_drv_state(edev->cdev, false);
+	if (edev->cdev)
+		edev->ops->common->update_drv_state(edev->cdev, false);
 
 	return 0;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 net-next 02/11] qed/qede: make devlink survive recovery
  2020-07-29 11:38 ` [PATCH v3 net-next 02/11] qed/qede: make devlink survive recovery Igor Russkikh
@ 2020-07-29 12:49   ` Jiri Pirko
  0 siblings, 0 replies; 17+ messages in thread
From: Jiri Pirko @ 2020-07-29 12:49 UTC (permalink / raw)
  To: Igor Russkikh
  Cc: netdev, David S . Miller, Jakub Kicinski, Ariel Elior,
	Michal Kalderon, Alexander Lobakin, Michal Kalderon

Wed, Jul 29, 2020 at 01:38:37PM CEST, irusskikh@marvell.com wrote:
>Before that, devlink instance lifecycle was linked to qed_dev object,

Before what?


>that causes devlink to be recreated on each recovery.
>
>Changing it by making higher level driver (qede) responsible for its
>life. This way devlink will survive recoveries.
>
>qede will store devlink structure pointer as a part of its device
>object, devlink private data contains a linkage structure, it'll
>contain extra devlink related content in following patches.
>
>The same lifecycle should be applied to storage drivers (qedf/qedi) later.

From this, one can't really tell if you are talking about existing state
or about the matter of this patch. In the patch description, you should
be imperative to the codebase telling it what to do. Could you please do
that?


>
>Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
>Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
>Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
>---
> drivers/net/ethernet/qlogic/qed/qed.h         |  1 -
> drivers/net/ethernet/qlogic/qed/qed_devlink.c | 40 ++++++++-----------
> drivers/net/ethernet/qlogic/qed/qed_devlink.h |  4 +-
> drivers/net/ethernet/qlogic/qed/qed_main.c    | 10 +----
> drivers/net/ethernet/qlogic/qede/qede.h       |  1 +
> drivers/net/ethernet/qlogic/qede/qede_main.c  | 18 +++++++++
> include/linux/qed/qed_if.h                    |  9 +++++
> 7 files changed, 48 insertions(+), 35 deletions(-)
>
>diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
>index b2a7b53ee760..b6ce1488abcc 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed.h
>+++ b/drivers/net/ethernet/qlogic/qed/qed.h
>@@ -849,7 +849,6 @@ struct qed_dev {
> 	u32 rdma_max_srq_sge;
> 	u16 tunn_feature_mask;
> 
>-	struct devlink			*dl;
> 	bool				iwarp_cmt;
> };
> 
>diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>index eb693787c99e..a62c47c61edf 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>@@ -5,6 +5,7 @@
>  */
> 
> #include <linux/kernel.h>
>+#include <linux/qed/qed_if.h>
> #include "qed.h"
> #include "qed_devlink.h"
> 
>@@ -13,17 +14,12 @@ enum qed_devlink_param_id {
> 	QED_DEVLINK_PARAM_ID_IWARP_CMT,
> };
> 
>-struct qed_devlink {
>-	struct qed_dev *cdev;
>-};
>-
> static int qed_dl_param_get(struct devlink *dl, u32 id,
> 			    struct devlink_param_gset_ctx *ctx)
> {
>-	struct qed_devlink *qed_dl;
>+	struct qed_devlink *qed_dl = devlink_priv(dl);
> 	struct qed_dev *cdev;
> 
>-	qed_dl = devlink_priv(dl);
> 	cdev = qed_dl->cdev;
> 	ctx->val.vbool = cdev->iwarp_cmt;
> 
>@@ -33,10 +29,9 @@ static int qed_dl_param_get(struct devlink *dl, u32 id,
> static int qed_dl_param_set(struct devlink *dl, u32 id,
> 			    struct devlink_param_gset_ctx *ctx)
> {
>-	struct qed_devlink *qed_dl;
>+	struct qed_devlink *qed_dl = devlink_priv(dl);
> 	struct qed_dev *cdev;
> 
>-	qed_dl = devlink_priv(dl);
> 	cdev = qed_dl->cdev;
> 	cdev->iwarp_cmt = ctx->val.vbool;
> 
>@@ -52,21 +47,19 @@ static const struct devlink_param qed_devlink_params[] = {
> 
> static const struct devlink_ops qed_dl_ops;
> 
>-int qed_devlink_register(struct qed_dev *cdev)
>+struct devlink *qed_devlink_register(struct qed_dev *cdev)
> {
> 	union devlink_param_value value;
>-	struct qed_devlink *qed_dl;
>+	struct qed_devlink *qdevlink;
> 	struct devlink *dl;
> 	int rc;
> 
>-	dl = devlink_alloc(&qed_dl_ops, sizeof(*qed_dl));
>+	dl = devlink_alloc(&qed_dl_ops, sizeof(struct qed_devlink));

Do "sizeof(*qdevlink)" instead.


> 	if (!dl)
>-		return -ENOMEM;
>+		return ERR_PTR(-ENOMEM);
> 
>-	qed_dl = devlink_priv(dl);
>-
>-	cdev->dl = dl;
>-	qed_dl->cdev = cdev;
>+	qdevlink = devlink_priv(dl);
>+	qdevlink->cdev = cdev;
> 
> 	rc = devlink_register(dl, &cdev->pdev->dev);
> 	if (rc)
>@@ -85,26 +78,25 @@ int qed_devlink_register(struct qed_dev *cdev)
> 	devlink_params_publish(dl);
> 	cdev->iwarp_cmt = false;
> 
>-	return 0;
>+	return dl;
> 
> err_unregister:
> 	devlink_unregister(dl);
> 
> err_free:
>-	cdev->dl = NULL;
> 	devlink_free(dl);
> 
>-	return rc;
>+	return ERR_PTR(rc);
> }
> 
>-void qed_devlink_unregister(struct qed_dev *cdev)
>+void qed_devlink_unregister(struct devlink *devlink)
> {
>-	if (!cdev->dl)
>+	if (!devlink)
> 		return;
> 
>-	devlink_params_unregister(cdev->dl, qed_devlink_params,
>+	devlink_params_unregister(devlink, qed_devlink_params,
> 				  ARRAY_SIZE(qed_devlink_params));
> 
>-	devlink_unregister(cdev->dl);
>-	devlink_free(cdev->dl);
>+	devlink_unregister(devlink);
>+	devlink_free(devlink);
> }
>diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.h b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
>index b94c40e9b7c1..c79dc6bfa194 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.h
>+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
>@@ -9,7 +9,7 @@
> #include <linux/qed/qed_if.h>
> #include <net/devlink.h>
> 
>-int qed_devlink_register(struct qed_dev *cdev);
>-void qed_devlink_unregister(struct qed_dev *cdev);
>+struct devlink *qed_devlink_register(struct qed_dev *cdev);
>+void qed_devlink_unregister(struct devlink *devlink);
> 
> #endif
>diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
>index 8751355d9ef7..d6f76421379b 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
>+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
>@@ -539,12 +539,6 @@ static struct qed_dev *qed_probe(struct pci_dev *pdev,
> 	}
> 	DP_INFO(cdev, "PCI init completed successfully\n");
> 
>-	rc = qed_devlink_register(cdev);
>-	if (rc) {
>-		DP_INFO(cdev, "Failed to register devlink.\n");
>-		goto err2;
>-	}
>-
> 	rc = qed_hw_prepare(cdev, QED_PCI_DEFAULT);
> 	if (rc) {
> 		DP_ERR(cdev, "hw prepare failed\n");
>@@ -574,8 +568,6 @@ static void qed_remove(struct qed_dev *cdev)
> 
> 	qed_set_power_state(cdev, PCI_D3hot);
> 
>-	qed_devlink_unregister(cdev);
>-
> 	qed_free_cdev(cdev);
> }
> 
>@@ -3012,6 +3004,8 @@ const struct qed_common_ops qed_common_ops_pass = {
> 	.get_link = &qed_get_current_link,
> 	.drain = &qed_drain,
> 	.update_msglvl = &qed_init_dp,
>+	.devlink_register = qed_devlink_register,
>+	.devlink_unregister = qed_devlink_unregister,
> 	.dbg_all_data = &qed_dbg_all_data,
> 	.dbg_all_data_size = &qed_dbg_all_data_size,
> 	.chain_alloc = &qed_chain_alloc,
>diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
>index 803c1fcca8ad..1f0e7505a973 100644
>--- a/drivers/net/ethernet/qlogic/qede/qede.h
>+++ b/drivers/net/ethernet/qlogic/qede/qede.h
>@@ -172,6 +172,7 @@ struct qede_dev {
> 	struct qed_dev			*cdev;
> 	struct net_device		*ndev;
> 	struct pci_dev			*pdev;
>+	struct devlink			*devlink;
> 
> 	u32				dp_module;
> 	u8				dp_level;
>diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
>index 1aaae3203f5a..7c2d948b2035 100644
>--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
>+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
>@@ -1172,10 +1172,23 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
> 			rc = -ENOMEM;
> 			goto err2;
> 		}
>+
>+		edev->devlink = qed_ops->common->devlink_register(cdev);
>+		if (IS_ERR(edev->devlink)) {
>+			DP_NOTICE(edev, "Cannot register devlink\n");
>+			edev->devlink = NULL;
>+			/* Go on, we can live without devlink */

Interesting. Why? This can happen only very pressing memory
circumstances. In that case, you should just fail to init. 


>+		}
> 	} else {
> 		struct net_device *ndev = pci_get_drvdata(pdev);
> 
> 		edev = netdev_priv(ndev);
>+
>+		if (edev && edev->devlink) {
>+			struct qed_devlink *qdl = devlink_priv(edev->devlink);
>+
>+			qdl->cdev = cdev;
>+		}
> 		edev->cdev = cdev;
> 		memset(&edev->stats, 0, sizeof(edev->stats));
> 		memcpy(&edev->dev_info, &dev_info, sizeof(dev_info));
>@@ -1298,6 +1311,11 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
> 	qed_ops->common->slowpath_stop(cdev);
> 	if (system_state == SYSTEM_POWER_OFF)
> 		return;
>+
>+	if (mode != QEDE_REMOVE_RECOVERY && edev->devlink) {
>+		qed_ops->common->devlink_unregister(edev->devlink);
>+		edev->devlink = NULL;
>+	}
> 	qed_ops->common->remove(cdev);
> 	edev->cdev = NULL;
> 
>diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
>index cd6a5c7e56eb..d8368e1770df 100644
>--- a/include/linux/qed/qed_if.h
>+++ b/include/linux/qed/qed_if.h
>@@ -21,6 +21,7 @@
> #include <linux/qed/common_hsi.h>
> #include <linux/qed/qed_chain.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
>+#include <net/devlink.h>
> 
> enum dcbx_protocol_type {
> 	DCBX_PROTOCOL_ISCSI,
>@@ -779,6 +780,10 @@ enum qed_nvm_flash_cmd {
> 	QED_NVM_FLASH_CMD_NVM_MAX,
> };
> 
>+struct qed_devlink {
>+	struct qed_dev *cdev;
>+};
>+
> struct qed_common_cb_ops {
> 	void (*arfs_filter_op)(void *dev, void *fltr, u8 fw_rc);
> 	void (*link_update)(void *dev, struct qed_link_output *link);
>@@ -1137,6 +1142,10 @@ struct qed_common_ops {
>  *
>  */
> 	int (*set_grc_config)(struct qed_dev *cdev, u32 cfg_id, u32 val);
>+
>+	struct devlink* (*devlink_register)(struct qed_dev *cdev);
>+
>+	void (*devlink_unregister)(struct devlink *devlink);
> };
> 
> #define MASK_FIELD(_name, _value) \
>-- 
>2.17.1
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 net-next 03/11] qed: swap param init and publish
  2020-07-29 11:38 ` [PATCH v3 net-next 03/11] qed: swap param init and publish Igor Russkikh
@ 2020-07-29 12:51   ` Jiri Pirko
  0 siblings, 0 replies; 17+ messages in thread
From: Jiri Pirko @ 2020-07-29 12:51 UTC (permalink / raw)
  To: Igor Russkikh
  Cc: netdev, David S . Miller, Jakub Kicinski, Ariel Elior,
	Michal Kalderon, Alexander Lobakin, Michal Kalderon

Wed, Jul 29, 2020 at 01:38:38PM CEST, irusskikh@marvell.com wrote:
>In theory that could lead to race condition

Describe the problem, tell the codebase what to do.

Plus, this looks like a -net material. Please consider pushing this
separatelly with proper "fixes" tag.


>
>Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
>Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
>Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
>---
> drivers/net/ethernet/qlogic/qed/qed_devlink.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>index a62c47c61edf..4e3316c6beb6 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>@@ -75,8 +75,8 @@ struct devlink *qed_devlink_register(struct qed_dev *cdev)
> 					   QED_DEVLINK_PARAM_ID_IWARP_CMT,
> 					   value);
> 
>-	devlink_params_publish(dl);
> 	cdev->iwarp_cmt = false;
>+	devlink_params_publish(dl);
> 
> 	return dl;
> 
>-- 
>2.17.1
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 net-next 05/11] qed: implement devlink info request
  2020-07-29 11:38 ` [PATCH v3 net-next 05/11] qed: implement devlink info request Igor Russkikh
@ 2020-07-29 12:52   ` Jiri Pirko
  0 siblings, 0 replies; 17+ messages in thread
From: Jiri Pirko @ 2020-07-29 12:52 UTC (permalink / raw)
  To: Igor Russkikh
  Cc: netdev, David S . Miller, Jakub Kicinski, Ariel Elior,
	Michal Kalderon, Alexander Lobakin, Michal Kalderon

Wed, Jul 29, 2020 at 01:38:40PM CEST, irusskikh@marvell.com wrote:
>Here we return existing fw & mfw versions, we also fetch device's
>serial number.
>
>The base device specific structure (qed_dev_info) was not directly
>available to the base driver before.
>Thus, here we create and store a private copy of this structure
>in qed_dev root object.
>
>Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
>Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
>Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
>---
> drivers/net/ethernet/qlogic/qed/qed.h         |  1 +
> drivers/net/ethernet/qlogic/qed/qed_dev.c     | 10 ++++
> drivers/net/ethernet/qlogic/qed/qed_devlink.c | 52 ++++++++++++++++++-
> drivers/net/ethernet/qlogic/qed/qed_main.c    |  1 +
> 4 files changed, 63 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
>index b6ce1488abcc..ccd789eeda3e 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed.h
>+++ b/drivers/net/ethernet/qlogic/qed/qed.h
>@@ -807,6 +807,7 @@ struct qed_dev {
> 	struct qed_llh_info *p_llh_info;
> 
> 	/* Linux specific here */
>+	struct qed_dev_info		common_dev_info;
> 	struct  qede_dev		*edev;
> 	struct  pci_dev			*pdev;
> 	u32 flags;
>diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
>index b3c9ebaf2280..377950ce8ea2 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
>+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
>@@ -4290,6 +4290,16 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
> 		__set_bit(QED_DEV_CAP_ROCE,
> 			  &p_hwfn->hw_info.device_capabilities);
> 
>+	/* Read device serial number information from shmem */
>+	addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
>+		offsetof(struct nvm_cfg1, glob) +
>+		offsetof(struct nvm_cfg1_glob, serial_number);
>+
>+	p_hwfn->hw_info.part_num[0] = qed_rd(p_hwfn, p_ptt, addr);
>+	p_hwfn->hw_info.part_num[1] = qed_rd(p_hwfn, p_ptt, addr + 4);
>+	p_hwfn->hw_info.part_num[2] = qed_rd(p_hwfn, p_ptt, addr + 8);
>+	p_hwfn->hw_info.part_num[3] = qed_rd(p_hwfn, p_ptt, addr + 12);

for() ?


>+
> 	return qed_mcp_fill_shmem_func_info(p_hwfn, p_ptt);
> }
> 
>diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>index 4e3316c6beb6..5bd5528dc409 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>@@ -45,7 +45,57 @@ static const struct devlink_param qed_devlink_params[] = {
> 			     qed_dl_param_get, qed_dl_param_set, NULL),
> };
> 
>-static const struct devlink_ops qed_dl_ops;
>+static int qed_devlink_info_get(struct devlink *devlink,
>+				struct devlink_info_req *req,
>+				struct netlink_ext_ack *extack)
>+{
>+	struct qed_devlink *qed_dl = devlink_priv(devlink);
>+	struct qed_dev *cdev = qed_dl->cdev;
>+	struct qed_dev_info *dev_info;
>+	char buf[100];
>+	int err;
>+
>+	dev_info = &cdev->common_dev_info;
>+
>+	err = devlink_info_driver_name_put(req, KBUILD_MODNAME);
>+	if (err)
>+		return err;
>+
>+	memcpy(buf, cdev->hwfns[0].hw_info.part_num, sizeof(cdev->hwfns[0].hw_info.part_num));
>+	buf[sizeof(cdev->hwfns[0].hw_info.part_num)] = 0;
>+
>+	if (buf[0]) {
>+		err = devlink_info_serial_number_put(req, buf);
>+		if (err)
>+			return err;
>+	}
>+
>+	snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
>+		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_3),
>+		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_2),
>+		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_1),
>+		 GET_MFW_FIELD(dev_info->mfw_rev, QED_MFW_VERSION_0));
>+
>+	err = devlink_info_version_stored_put(req,
>+					      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, buf);
>+	if (err)
>+		return err;
>+
>+	snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
>+		 dev_info->fw_major,
>+		 dev_info->fw_minor,
>+		 dev_info->fw_rev,
>+		 dev_info->fw_eng);
>+
>+	err = devlink_info_version_running_put(req,
>+					       DEVLINK_INFO_VERSION_GENERIC_FW, buf);

return = devlink...


>+
>+	return err;
>+}
>+
>+static const struct devlink_ops qed_dl_ops = {
>+	.info_get = qed_devlink_info_get,
>+};
> 
> struct devlink *qed_devlink_register(struct qed_dev *cdev)
> {
>diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
>index d6f76421379b..d1a559ccf516 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
>+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
>@@ -479,6 +479,7 @@ int qed_fill_dev_info(struct qed_dev *cdev,
> 	}
> 
> 	dev_info->mtu = hw_info->mtu;
>+	cdev->common_dev_info = *dev_info;
> 
> 	return 0;
> }
>-- 
>2.17.1
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 net-next 07/11] qed: use devlink logic to report errors
  2020-07-29 11:38 ` [PATCH v3 net-next 07/11] qed: use devlink logic to report errors Igor Russkikh
@ 2020-07-29 13:08   ` Jiri Pirko
  2020-07-30  8:30     ` [EXT] " Igor Russkikh
  0 siblings, 1 reply; 17+ messages in thread
From: Jiri Pirko @ 2020-07-29 13:08 UTC (permalink / raw)
  To: Igor Russkikh
  Cc: netdev, David S . Miller, Jakub Kicinski, Ariel Elior,
	Michal Kalderon, Alexander Lobakin, Michal Kalderon

Wed, Jul 29, 2020 at 01:38:42PM CEST, irusskikh@marvell.com wrote:
>Use devlink_health_report to push error indications.
>We implement this in qede via callback function to make it possible
>to reuse the same for other drivers sitting on top of qed in future.
>
>Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
>Signed-off-by: Alexander Lobakin <alobakin@marvell.com>
>Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
>---
> drivers/net/ethernet/qlogic/qed/qed_devlink.c | 17 +++++++++++++++++
> drivers/net/ethernet/qlogic/qed/qed_devlink.h |  2 ++
> drivers/net/ethernet/qlogic/qed/qed_main.c    |  1 +
> drivers/net/ethernet/qlogic/qede/qede.h       |  1 +
> drivers/net/ethernet/qlogic/qede/qede_main.c  |  5 ++++-
> include/linux/qed/qed_if.h                    |  3 +++
> 6 files changed, 28 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>index 843a35f14cca..ffe776a4f99a 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
>@@ -14,6 +14,23 @@ enum qed_devlink_param_id {
> 	QED_DEVLINK_PARAM_ID_IWARP_CMT,
> };
> 
>+struct qed_fw_fatal_ctx {
>+	enum qed_hw_err_type err_type;
>+};
>+
>+int qed_report_fatal_error(struct devlink *devlink, enum qed_hw_err_type err_type)
>+{
>+	struct qed_devlink *qdl = devlink_priv(devlink);
>+	struct qed_fw_fatal_ctx fw_fatal_ctx = {
>+		.err_type = err_type,
>+	};
>+
>+	devlink_health_report(qdl->fw_reporter,
>+			      "Fatal error reported", &fw_fatal_ctx);

saying "reported" to the reporter sounds odd. Maybe occurred?


>+
>+	return 0;
>+}
>+
> static const struct devlink_health_reporter_ops qed_fw_fatal_reporter_ops = {
> 		.name = "fw_fatal",
> };
>diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.h b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
>index c68ecf778826..ccc7d1d1bfd4 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.h
>+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.h
>@@ -15,4 +15,6 @@ void qed_devlink_unregister(struct devlink *devlink);
> void qed_fw_reporters_create(struct devlink *devlink);
> void qed_fw_reporters_destroy(struct devlink *devlink);
> 
>+int qed_report_fatal_error(struct devlink *dl, enum qed_hw_err_type err_type);
>+
> #endif
>diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
>index d1a559ccf516..a64d594f9294 100644
>--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
>+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
>@@ -3007,6 +3007,7 @@ const struct qed_common_ops qed_common_ops_pass = {
> 	.update_msglvl = &qed_init_dp,
> 	.devlink_register = qed_devlink_register,
> 	.devlink_unregister = qed_devlink_unregister,
>+	.report_fatal_error = qed_report_fatal_error,
> 	.dbg_all_data = &qed_dbg_all_data,
> 	.dbg_all_data_size = &qed_dbg_all_data_size,
> 	.chain_alloc = &qed_chain_alloc,
>diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
>index 1f0e7505a973..3efc5899f656 100644
>--- a/drivers/net/ethernet/qlogic/qede/qede.h
>+++ b/drivers/net/ethernet/qlogic/qede/qede.h
>@@ -264,6 +264,7 @@ struct qede_dev {
> 
> 	struct bpf_prog			*xdp_prog;
> 
>+	enum qed_hw_err_type		last_err_type;
> 	unsigned long			err_flags;
> #define QEDE_ERR_IS_HANDLED		31
> #define QEDE_ERR_ATTN_CLR_EN		0
>diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
>index 7c2d948b2035..df437c3f1fc9 100644
>--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
>+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
>@@ -1181,7 +1181,6 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
> 		}
> 	} else {
> 		struct net_device *ndev = pci_get_drvdata(pdev);
>-

Leftover. Please remove.


> 		edev = netdev_priv(ndev);
> 
> 		if (edev && edev->devlink) {
>@@ -2603,6 +2602,9 @@ static void qede_generic_hw_err_handler(struct qede_dev *edev)
> 		  "Generic sleepable HW error handling started - err_flags 0x%lx\n",
> 		  edev->err_flags);
> 
>+	if (edev->devlink)
>+		edev->ops->common->report_fatal_error(edev->devlink, edev->last_err_type);
>+
> 	/* Trigger a recovery process.
> 	 * This is placed in the sleep requiring section just to make
> 	 * sure it is the last one, and that all the other operations
>@@ -2663,6 +2665,7 @@ static void qede_schedule_hw_err_handler(void *dev,
> 		return;
> 	}
> 
>+	edev->last_err_type = err_type;
> 	qede_set_hw_err_flags(edev, err_type);
> 	qede_atomic_hw_err_handler(edev);
> 	set_bit(QEDE_SP_HW_ERR, &edev->sp_flags);
>diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
>index 30fe06fe06a0..1297726f2b25 100644
>--- a/include/linux/qed/qed_if.h
>+++ b/include/linux/qed/qed_if.h
>@@ -906,6 +906,9 @@ struct qed_common_ops {
> 
> 	int (*dbg_all_data_size) (struct qed_dev *cdev);
> 
>+	int		(*report_fatal_error)(struct devlink *devlink,
>+					      enum qed_hw_err_type err_type);
>+
> /**
>  * @brief can_link_change - can the instance change the link or not
>  *
>-- 
>2.17.1
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [EXT] Re: [PATCH v3 net-next 07/11] qed: use devlink logic to report errors
  2020-07-29 13:08   ` Jiri Pirko
@ 2020-07-30  8:30     ` Igor Russkikh
  0 siblings, 0 replies; 17+ messages in thread
From: Igor Russkikh @ 2020-07-30  8:30 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, David S . Miller, Jakub Kicinski, Ariel Elior,
	Michal Kalderon, Alexander Lobakin



On 29/07/2020 4:08 pm, Jiri Pirko wrote:
> 
> ----------------------------------------------------------------------
> Wed, Jul 29, 2020 at 01:38:42PM CEST, irusskikh@marvell.com wrote:
>> Use devlink_health_report to push error indications.
>> We implement this in qede via callback function to make it possible
>> to reuse the same for other drivers sitting on top of qed in future.

Hi Jiri, thanks for your review, all looks reasonable, fixing now!

Regards,
  Igor

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-07-30  8:30 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-29 11:38 [PATCH v3 net-next 00/11] qed: introduce devlink health support Igor Russkikh
2020-07-29 11:38 ` [PATCH v3 net-next 01/11] qed: move out devlink logic into a new file Igor Russkikh
2020-07-29 11:38 ` [PATCH v3 net-next 02/11] qed/qede: make devlink survive recovery Igor Russkikh
2020-07-29 12:49   ` Jiri Pirko
2020-07-29 11:38 ` [PATCH v3 net-next 03/11] qed: swap param init and publish Igor Russkikh
2020-07-29 12:51   ` Jiri Pirko
2020-07-29 11:38 ` [PATCH v3 net-next 04/11] qed: fix kconfig help entries Igor Russkikh
2020-07-29 11:38 ` [PATCH v3 net-next 05/11] qed: implement devlink info request Igor Russkikh
2020-07-29 12:52   ` Jiri Pirko
2020-07-29 11:38 ` [PATCH v3 net-next 06/11] qed: health reporter init deinit seq Igor Russkikh
2020-07-29 11:38 ` [PATCH v3 net-next 07/11] qed: use devlink logic to report errors Igor Russkikh
2020-07-29 13:08   ` Jiri Pirko
2020-07-30  8:30     ` [EXT] " Igor Russkikh
2020-07-29 11:38 ` [PATCH v3 net-next 08/11] qed*: make use of devlink recovery infrastructure Igor Russkikh
2020-07-29 11:38 ` [PATCH v3 net-next 09/11] qed: implement devlink dump Igor Russkikh
2020-07-29 11:38 ` [PATCH v3 net-next 10/11] qed: align adjacent indent Igor Russkikh
2020-07-29 11:38 ` [PATCH v3 net-next 11/11] qede: make driver reliable on unload after failures Igor Russkikh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.