* [PATCH] atm: idt77252: avoid accessing the data mapped to streaming DMA
From: Jia-Ju Bai @ 2020-08-02 9:33 UTC (permalink / raw)
To: 3chas3; +Cc: linux-atm-general, netdev, linux-kernel, Jia-Ju Bai
In queue_skb(), skb->data is mapped to streaming DMA on line 850:
dma_map_single(..., skb->data, ...);
Then skb->data is accessed on lines 862 and 863:
tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
(skb->data[2] << 8) | (skb->data[3] << 0);
and on lines 893 and 894:
tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
(skb->data[2] << 8) | (skb->data[3] << 0);
These accesses may cause data inconsistency between CPU cache and
hardware.
To fix this problem, the calculation result of skb->data is stored in a
local variable before DMA mapping, and then the driver accesses this
local variable instead of skb->data.
Signed-off-by: Jia-Ju Bai <baijiaju@tsinghua.edu.cn>
---
drivers/atm/idt77252.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index df51680e8931..65a3886f68c9 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -835,6 +835,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
unsigned long flags;
int error;
int aal;
+ u32 word4;
if (skb->len == 0) {
printk("%s: invalid skb->len (%d)\n", card->name, skb->len);
@@ -846,6 +847,8 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
tbd = &IDT77252_PRV_TBD(skb);
vcc = ATM_SKB(skb)->vcc;
+ word4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
+ (skb->data[2] << 8) | (skb->data[3] << 0);
IDT77252_PRV_PADDR(skb) = dma_map_single(&card->pcidev->dev, skb->data,
skb->len, DMA_TO_DEVICE);
@@ -859,8 +862,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
tbd->word_1 = SAR_TBD_OAM | ATM_CELL_PAYLOAD | SAR_TBD_EPDU;
tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
tbd->word_3 = 0x00000000;
- tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
- (skb->data[2] << 8) | (skb->data[3] << 0);
+ tbd->word_4 = word4;
if (test_bit(VCF_RSV, &vc->flags))
vc = card->vcs[0];
@@ -890,8 +892,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
tbd->word_3 = 0x00000000;
- tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
- (skb->data[2] << 8) | (skb->data[3] << 0);
+ tbd->word_4 = word4;
break;
case ATM_AAL5:
--
2.17.1
^ permalink raw reply related
* [PATCH v5 net-next 00/10] qed: introduce devlink health support
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, 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.
v5: improved patch 4 description
v4:
- commit message and other fixes after Jiri's comments
- removed one patch (will send to net)
v3: fix uninit var usage in patch 11
v2: fix #include issue from kbuild test robot.
Igor Russkikh (10):
qed: move out devlink logic into a new file
qed/qede: make devlink survive recovery
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 | 9 +
drivers/net/ethernet/qlogic/qed/qed_devlink.c | 259 ++++++++++++++++++
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 | 38 ++-
include/linux/qed/qed_if.h | 23 +-
10 files changed, 347 insertions(+), 129 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
* [PATCH v5 net-next 01/10] qed: move out devlink logic into a new file
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, Igor Russkikh, Alexander Lobakin,
Michal Kalderon
In-Reply-To: <20200802100834.383-1-irusskikh@marvell.com>
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
* [PATCH v5 net-next 02/10] qed/qede: make devlink survive recovery
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, Igor Russkikh, Alexander Lobakin,
Michal Kalderon
In-Reply-To: <20200802100834.383-1-irusskikh@marvell.com>
Devlink instance lifecycle was linked to qed_dev object,
that caused devlink to be recreated on each recovery.
Changing it by making higher level driver (qede) responsible for its
life. This way devlink now survives recoveries.
qede now stores devlink structure pointer as a part of its device
object, devlink private data contains a linkage structure,
qed_devlink.
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
* [PATCH v5 net-next 03/10] qed: fix kconfig help entries
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, Igor Russkikh, Alexander Lobakin,
Michal Kalderon
In-Reply-To: <20200802100834.383-1-irusskikh@marvell.com>
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
* [PATCH v5 net-next 04/10] qed: implement devlink info request
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, Igor Russkikh, Alexander Lobakin,
Michal Kalderon
In-Reply-To: <20200802100834.383-1-irusskikh@marvell.com>
Here we return existing fw & mfw versions, we also fetch device's
serial number:
~$ sudo ~/iproute2/devlink/devlink dev info
pci/0000:01:00.0:
driver qed
serial_number REE1915E44552
versions:
running:
fw 8.42.2.0
stored:
fw.mgmt 8.52.10.0
pci/0000:01:00.1:
driver qed
serial_number REE1915E44552
versions:
running:
fw 8.42.2.0
stored:
fw.mgmt 8.52.10.0
MFW and FW are different firmwares on device.
Management is a firmware responsible for link configuration and
various control plane features. Its permanent and resides in NVM.
Running FW (or fastpath FW) is an embedded microprogram implementing
all the packet processing, offloads, etc. This FW is being loaded
on each start by the driver from FW binary blob.
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 to
access the data.
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 | 9 ++++
drivers/net/ethernet/qlogic/qed/qed_devlink.c | 50 ++++++++++++++++++-
drivers/net/ethernet/qlogic/qed/qed_main.c | 1 +
4 files changed, 60 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..00f2d7f13de6 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -3973,6 +3973,7 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
struct qed_mcp_link_speed_params *ext_speed;
struct qed_mcp_link_capabilities *p_caps;
struct qed_mcp_link_params *link;
+ int i;
/* Read global nvm_cfg address */
nvm_cfg_addr = qed_rd(p_hwfn, p_ptt, MISC_REG_GEN_PURP_CR0);
@@ -4290,6 +4291,14 @@ 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);
+
+ for (i = 0; i < 4; i++)
+ p_hwfn->hw_info.part_num[i] = qed_rd(p_hwfn, p_ptt, addr + i * 4);
+
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 a62c47c61edf..57ef2c56c884 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -45,7 +45,55 @@ 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);
+
+ return devlink_info_version_running_put(req,
+ DEVLINK_INFO_VERSION_GENERIC_FW, buf);
+}
+
+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
* [PATCH v5 net-next 05/10] qed: health reporter init deinit seq
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, Igor Russkikh, Alexander Lobakin,
Michal Kalderon
In-Reply-To: <20200802100834.383-1-irusskikh@marvell.com>
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 | 34 +++++++++++++++++++
drivers/net/ethernet/qlogic/qed/qed_devlink.h | 3 ++
include/linux/qed/qed_if.h | 1 +
3 files changed, 38 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
index 57ef2c56c884..8d9150ecb580 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -14,6 +14,36 @@ 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));
+ dl->fw_reporter = NULL;
+ }
+}
+
+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)
{
@@ -126,6 +156,8 @@ struct devlink *qed_devlink_register(struct qed_dev *cdev)
devlink_params_publish(dl);
cdev->iwarp_cmt = false;
+ qed_fw_reporters_create(dl);
+
return dl;
err_unregister:
@@ -142,6 +174,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
* [PATCH v5 net-next 06/10] qed: use devlink logic to report errors
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, Igor Russkikh, Alexander Lobakin,
Michal Kalderon
In-Reply-To: <20200802100834.383-1-irusskikh@marvell.com>
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 | 18 ++++++++++++++++++
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 | 4 ++++
include/linux/qed/qed_if.h | 3 +++
6 files changed, 29 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
index 8d9150ecb580..e81bd3b39149 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -14,6 +14,24 @@ 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,
+ };
+
+ if (qdl->fw_reporter)
+ devlink_health_report(qdl->fw_reporter,
+ "Fatal error occurred", &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..9895affa5064 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -2603,6 +2603,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 +2666,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
* [PATCH v5 net-next 07/10] qed*: make use of devlink recovery infrastructure
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, Igor Russkikh, Alexander Lobakin,
Michal Kalderon
In-Reply-To: <20200802100834.383-1-irusskikh@marvell.com>
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 e81bd3b39149..1cf2199a3124 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c
@@ -32,8 +32,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 9895affa5064..287e10effb49 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -2597,8 +2597,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);
@@ -2606,14 +2604,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
* [PATCH v5 net-next 08/10] qed: implement devlink dump
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, Igor Russkikh, Alexander Lobakin,
Michal Kalderon
In-Reply-To: <20200802100834.383-1-irusskikh@marvell.com>
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 1cf2199a3124..4f6b1928edaf 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"
@@ -32,6 +33,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,
@@ -48,6 +90,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
* [PATCH v5 net-next 09/10] qed: align adjacent indent
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, Igor Russkikh, Alexander Lobakin,
Michal Kalderon
In-Reply-To: <20200802100834.383-1-irusskikh@marvell.com>
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
* [PATCH v5 net-next 10/10] qede: make driver reliable on unload after failures
From: Igor Russkikh @ 2020-08-02 10:08 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Jakub Kicinski, Ariel Elior, Michal Kalderon,
Denis Bolotin, Jiri Pirko, Igor Russkikh, Alexander Lobakin,
Michal Kalderon
In-Reply-To: <20200802100834.383-1-irusskikh@marvell.com>
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 287e10effb49..01a7bff91d6c 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -1240,7 +1240,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:
@@ -2475,7 +2478,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
* [PATCH] liquidio: Fix wrong return value in cn23xx_get_pf_num()
From: Tianjia Zhang @ 2020-08-02 11:15 UTC (permalink / raw)
To: dchickles, sburla, fmanlunas, davem, kuba, ricardo.farrington
Cc: netdev, linux-kernel, tianjia.zhang
On an error exit path, a negative error code should be returned
instead of a positive return value.
Fixes: 0c45d7fe12c7e ("liquidio: fix use of pf in pass-through mode in a virtual machine")
Cc: Rick Farrington <ricardo.farrington@cavium.com>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
---
drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
index 43d11c38b38a..4cddd628d41b 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
@@ -1167,7 +1167,7 @@ static int cn23xx_get_pf_num(struct octeon_device *oct)
oct->pf_num = ((fdl_bit >> CN23XX_PCIE_SRIOV_FDL_BIT_POS) &
CN23XX_PCIE_SRIOV_FDL_MASK);
} else {
- ret = EINVAL;
+ ret = -EINVAL;
/* Under some virtual environments, extended PCI regs are
* inaccessible, in which case the above read will have failed.
--
2.26.2
^ permalink raw reply related
* [PATCH] tools/bpf/bpftool: Fix wrong return value in do_dump()
From: Tianjia Zhang @ 2020-08-02 11:15 UTC (permalink / raw)
To: ast, daniel, kafai, songliubraving, yhs, andriin, john.fastabend,
kpsingh, quentin, kuba, toke, tklauser, tianjia.zhang, jolsa
Cc: netdev, bpf, linux-kernel, tianjia.zhang
In case of btf_id does not exist, a negative error code -ENOENT
should be returned.
Fixes: c93cc69004df3 ("bpftool: add ability to dump BTF types")
Cc: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
---
tools/bpf/bpftool/btf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index faac8189b285..c2f1fd414820 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -596,7 +596,7 @@ static int do_dump(int argc, char **argv)
goto done;
}
if (!btf) {
- err = ENOENT;
+ err = -ENOENT;
p_err("can't find btf with ID (%u)", btf_id);
goto done;
}
--
2.26.2
^ permalink raw reply related
* [PATCH] net/enetc: Fix wrong return value in enetc_psfp_parse_clsflower()
From: Tianjia Zhang @ 2020-08-02 11:15 UTC (permalink / raw)
To: claudiu.manoil, davem, kuba; +Cc: netdev, linux-kernel, tianjia.zhang
In the case of invalid rule, a positive value EINVAL is returned here.
I think this is a typo error. It is necessary to return an error value.
Cc: Po Liu <Po.Liu@nxp.com>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
---
drivers/net/ethernet/freescale/enetc/enetc_qos.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
index fd3df19eaa32..4b3f1b60a24b 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
@@ -1017,7 +1017,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
!is_zero_ether_addr(match.mask->src)) {
NL_SET_ERR_MSG_MOD(extack,
"Cannot match on both source and destination MAC");
- err = EINVAL;
+ err = -EINVAL;
goto free_filter;
}
@@ -1025,7 +1025,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
if (!is_broadcast_ether_addr(match.mask->dst)) {
NL_SET_ERR_MSG_MOD(extack,
"Masked matching on destination MAC not supported");
- err = EINVAL;
+ err = -EINVAL;
goto free_filter;
}
ether_addr_copy(filter->sid.dst_mac, match.key->dst);
@@ -1036,7 +1036,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
if (!is_broadcast_ether_addr(match.mask->src)) {
NL_SET_ERR_MSG_MOD(extack,
"Masked matching on source MAC not supported");
- err = EINVAL;
+ err = -EINVAL;
goto free_filter;
}
ether_addr_copy(filter->sid.src_mac, match.key->src);
@@ -1044,7 +1044,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
}
} else {
NL_SET_ERR_MSG_MOD(extack, "Unsupported, must include ETH_ADDRS");
- err = EINVAL;
+ err = -EINVAL;
goto free_filter;
}
--
2.26.2
^ permalink raw reply related
* [PATCH] net: ethernet: aquantia: Fix wrong return value
From: Tianjia Zhang @ 2020-08-02 11:15 UTC (permalink / raw)
To: irusskikh, davem, kuba, mstarovoitov, dbezrukov, ndanilov,
tianjia.zhang, Pavel.Belous, Alexander.Loktionov,
Dmitrii.Tarakanov
Cc: netdev, linux-kernel, tianjia.zhang
In function hw_atl_a0_hw_multicast_list_set(), when an invalid
request is encountered, a negative error code should be returned.
Fixes: bab6de8fd180b ("net: ethernet: aquantia: Atlantic A0 and B0 specific functions")
Cc: David VomLehn <vomlehn@texas.net>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
---
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index a312864969af..6640fd35b29b 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -782,7 +782,7 @@ static int hw_atl_a0_hw_multicast_list_set(struct aq_hw_s *self,
int err = 0;
if (count > (HW_ATL_A0_MAC_MAX - HW_ATL_A0_MAC_MIN)) {
- err = EBADRQC;
+ err = -EBADRQC;
goto err_exit;
}
for (self->aq_nic_cfg->mc_list_count = 0U;
--
2.26.2
^ permalink raw reply related
* [PATCH] ath10k: Fix the size used in a 'dma_free_coherent()' call in an error handling path
From: Christophe JAILLET @ 2020-08-02 12:22 UTC (permalink / raw)
To: kvalo, davem, kuba, pillair
Cc: ath10k, linux-wireless, netdev, linux-kernel, kernel-janitors,
Christophe JAILLET
Update the size used in 'dma_free_coherent()' in order to match the one
used in the corresponding 'dma_alloc_coherent()'.
Fixes: 1863008369ae ("ath10k: fix shadow register implementation for WCN3990")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
This patch looks obvious to me, but commit 1863008369ae looks also simple.
So it is surprising that such a "typo" slipped in.
---
drivers/net/wireless/ath/ath10k/ce.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 294fbc1e89ab..e6e0284e4783 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -1555,7 +1555,7 @@ ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id,
ret = ath10k_ce_alloc_shadow_base(ar, src_ring, nentries);
if (ret) {
dma_free_coherent(ar->dev,
- (nentries * sizeof(struct ce_desc_64) +
+ (nentries * sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN),
src_ring->base_addr_owner_space_unaligned,
base_addr);
--
2.25.1
^ permalink raw reply related
* [PATCH net v2] net: bridge: clear skb private space on bridge dev xmit
From: Nikolay Aleksandrov @ 2020-08-02 12:50 UTC (permalink / raw)
To: netdev; +Cc: davem, roopa, bridge, dsahern, Nikolay Aleksandrov
In-Reply-To: <39736ed8-8565-ab64-5163-da6f2acba68a@cumulusnetworks.com>
We need to clear all of the bridge private skb variables as they can be
stale due to the packet having skb->cb initialized earlier and then
transmitted through the bridge device. Similar memset is already done on
bridge's input. We've seen cases where proxyarp_replied was 1 on routed
multicast packets transmitted through the bridge to ports with neigh
suppress and were getting dropped. Same thing can in theory happen with the
port isolation bit as well. We clear only the struct part after the bridge
pointer (currently 8 bytes) since the pointer is always set later.
We can now remove the redundant zeroing of frag_max_size.
Also add a BUILD_BUG_ON to make sure we catch any movement of the bridge
dev pointer.
Fixes: 821f1b21cabb ("bridge: add new BR_NEIGH_SUPPRESS port flag to suppress arp and nd flood")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
v2: clear only the second half of the struct which contains the
fields that are used in various bridge parts, this replaced the rep stos
instruction with a single movq on my x86 and in general reduces
the clear area to 8 bytes, and in addition we can remove the now
redundant zeroing of frag_max_size as it will be already cleared,
add a build_bug_on to make sure we catch any movement of the bridge
dev pointer
net/bridge/br_device.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 8c7b78f8bc23..4f7880c99d3c 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -36,6 +36,12 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
const unsigned char *dest;
u16 vid = 0;
+ /* clear all private fields after the bridge dev pointer */
+ BUILD_BUG_ON(offsetof(struct br_input_skb_cb, brdev) > 0);
+ memset(skb->cb + sizeof(struct net_device *),
+ 0,
+ sizeof(struct br_input_skb_cb) - sizeof(struct net_device *));
+
rcu_read_lock();
nf_ops = rcu_dereference(nf_br_ops);
if (nf_ops && nf_ops->br_dev_xmit_hook(skb)) {
@@ -50,7 +56,6 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
br_switchdev_frame_unmark(skb);
BR_INPUT_SKB_CB(skb)->brdev = dev;
- BR_INPUT_SKB_CB(skb)->frag_max_size = 0;
skb_reset_mac_header(skb);
skb_pull(skb, ETH_HLEN);
--
2.25.4
^ permalink raw reply related
* [PATCH] net: vmxnet3: avoid accessing the data mapped to streaming DMA
From: Jia-Ju Bai @ 2020-08-02 13:11 UTC (permalink / raw)
To: doshir, pv-drivers, davem, kuba; +Cc: netdev, linux-kernel, Jia-Ju Bai
In vmxnet3_probe_device(), "adapter" is mapped to streaming DMA:
adapter->adapter_pa = dma_map_single(..., adapter, ...);
Then "adapter" is accessed at many places in this function.
Theses accesses may cause data inconsistency between CPU cache and
hardware.
To fix this problem, dma_map_single() is called after these accesses.
Signed-off-by: Jia-Ju Bai <baijiaju@tsinghua.edu.cn>
---
drivers/net/vmxnet3/vmxnet3_drv.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index ca395f9679d0..96a4c28ba429 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -3445,14 +3445,6 @@ vmxnet3_probe_device(struct pci_dev *pdev,
}
spin_lock_init(&adapter->cmd_lock);
- adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,
- sizeof(struct vmxnet3_adapter),
- PCI_DMA_TODEVICE);
- if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) {
- dev_err(&pdev->dev, "Failed to map dma\n");
- err = -EFAULT;
- goto err_set_mask;
- }
adapter->shared = dma_alloc_coherent(
&adapter->pdev->dev,
sizeof(struct Vmxnet3_DriverShared),
@@ -3628,6 +3620,16 @@ vmxnet3_probe_device(struct pci_dev *pdev,
}
vmxnet3_check_link(adapter, false);
+
+ adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,
+ sizeof(struct vmxnet3_adapter),
+ PCI_DMA_TODEVICE);
+ if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) {
+ dev_err(&pdev->dev, "Failed to map dma\n");
+ err = -EFAULT;
+ goto err_register;
+ }
+
return 0;
err_register:
@@ -3655,8 +3657,6 @@ vmxnet3_probe_device(struct pci_dev *pdev,
sizeof(struct Vmxnet3_DriverShared),
adapter->shared, adapter->shared_pa);
err_alloc_shared:
- dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa,
- sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE);
err_set_mask:
free_netdev(netdev);
return err;
--
2.17.1
^ permalink raw reply related
* Re: [PATCH 1/2 v2 net-next] 8390: Miscellaneous cleanups
From: Armin Wolf @ 2020-08-02 13:14 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: netdev
In-Reply-To: <20200801213204.0a52a865@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
On Sat, Aug 01, 2020 at 09:32:04PM -0700, Jakub Kicinski wrote:
> On Sat, 1 Aug 2020 22:52:42 +0200 Armin Wolf wrote:
> > Replace version string with MODULE_* macros.
> >
> > Include necessary libraries.
> >
> > Fix two minor coding-style issues.
> >
> > Signed-off-by: Armin Wolf <W_Armin@gmx.de>
>
> This doesn't build but also
>
> ../drivers/net/ethernet/8390/lib8390.c:973:17: error: undefined identifier 'version'
> In file included from ../include/linux/kernel.h:15,
> from ../drivers/net/ethernet/8390/8390.c:9:
> ../drivers/net/ethernet/8390/lib8390.c: In function ‘ethdev_setup’:
> ../drivers/net/ethernet/8390/lib8390.c:973:17: error: ‘version’ undeclared (first use in this function)
> 973 | pr_info("%s", version);
> | ^~~~~~~
> ../include/linux/printk.h:368:34: note: in definition of macro ‘pr_info’
> 368 | printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
> | ^~~~~~~~~~~
> ../drivers/net/ethernet/8390/lib8390.c:973:17: note: each undeclared identifier is reported only once for each function it appears in
> 973 | pr_info("%s", version);
> | ^~~~~~~
> ../include/linux/printk.h:368:34: note: in definition of macro ‘pr_info’
> 368 | printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
> | ^~~~~~~~~~~
> make[5]: *** [../scripts/Makefile.build:281: drivers/net/ethernet/8390/8390.o] Error 1
> make[4]: *** [../scripts/Makefile.build:497: drivers/net/ethernet/8390] Error 2
> make[4]: *** Waiting for unfinished jobs....
> make[3]: *** [../scripts/Makefile.build:497: drivers/net/ethernet] Error 2
> make[3]: *** Waiting for unfinished jobs....
> make[2]: *** [../scripts/Makefile.build:497: drivers/net] Error 2
> make[2]: *** Waiting for unfinished jobs....
> make[1]: *** [/netdev/net-next/Makefile:1771: drivers] Error 2
> make: *** [Makefile:185: __sub-make] Error 2
Did you apply patch 2/2 of the patchset?
Because version-printing (and the need for a version string) was removed
from lib8390.c in patch 2/2 to allow the replacement of said
version-string with MODULE_* macros in 8390.c, and failing to do so whould result
in the exact same error.
^ permalink raw reply
* Re: [PATCH net-next v3 2/2] net: dsa: qca8k: Add 802.1q VLAN support
From: Vladimir Oltean @ 2020-08-02 13:21 UTC (permalink / raw)
To: Jonathan McDowell
Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David Miller,
Jakub Kicinski, Russell King - ARM Linux admin, Matthew Hagan,
netdev, linux-kernel
In-Reply-To: <ec320e8e5a9691b85ee79f6ef03f1b0b6a562655.1596301468.git.noodles@earth.li>
On Sat, Aug 01, 2020 at 06:06:46PM +0100, Jonathan McDowell wrote:
> This adds full 802.1q VLAN support to the qca8k, allowing the use of
> vlan_filtering and more complicated bridging setups than allowed by
> basic port VLAN support.
>
> Tested with a number of untagged ports with separate VLANs and then a
> trunk port with all the VLANs tagged on it.
>
> v3:
> - Pull QCA8K_PORT_VID_DEF changes into separate cleanup patch
> - Reverse Christmas tree notation for variable definitions
> - Use untagged instead of tagged for consistency
> v2:
> - Return sensible errnos on failure rather than -1 (rmk)
> - Style cleanups based on Florian's feedback
> - Silently allow VLAN 0 as device correctly treats this as no tag
>
> Signed-off-by: Jonathan McDowell <noodles@earth.li>
> ---
My comments have been addressed, thanks.
Acked-by: Vladimir Oltean <olteanv@gmail.com>
> drivers/net/dsa/qca8k.c | 181 ++++++++++++++++++++++++++++++++++++++++
> drivers/net/dsa/qca8k.h | 27 ++++++
> 2 files changed, 208 insertions(+)
>
> diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> index 3ebc4da63074..f1e484477e35 100644
> --- a/drivers/net/dsa/qca8k.c
> +++ b/drivers/net/dsa/qca8k.c
> @@ -408,6 +408,112 @@ qca8k_fdb_flush(struct qca8k_priv *priv)
> mutex_unlock(&priv->reg_mutex);
> }
>
> +static int
> +qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
> +{
> + u32 reg;
> +
> + /* Set the command and VLAN index */
> + reg = QCA8K_VTU_FUNC1_BUSY;
> + reg |= cmd;
> + reg |= vid << QCA8K_VTU_FUNC1_VID_S;
> +
> + /* Write the function register triggering the table access */
> + qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
> +
> + /* wait for completion */
> + if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
> + return -ETIMEDOUT;
> +
> + /* Check for table full violation when adding an entry */
> + if (cmd == QCA8K_VLAN_LOAD) {
> + reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
> + if (reg & QCA8K_VTU_FUNC1_FULL)
> + return -ENOMEM;
> + }
> +
> + return 0;
> +}
> +
> +static int
> +qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged)
> +{
> + u32 reg;
> + int ret;
> +
> + /*
> + We do the right thing with VLAN 0 and treat it as untagged while
> + preserving the tag on egress.
> + */
> + if (vid == 0)
> + return 0;
> +
> + mutex_lock(&priv->reg_mutex);
> + ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
> + if (ret < 0)
> + goto out;
> +
> + reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
> + reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
> + reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port));
> + if (untagged)
> + reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG <<
> + QCA8K_VTU_FUNC0_EG_MODE_S(port);
> + else
> + reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
> + QCA8K_VTU_FUNC0_EG_MODE_S(port);
> +
> + qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
> + ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
> +
> +out:
> + mutex_unlock(&priv->reg_mutex);
> +
> + return ret;
> +}
> +
> +static int
> +qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
> +{
> + u32 reg, mask;
> + int ret, i;
> + bool del;
> +
> + mutex_lock(&priv->reg_mutex);
> + ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
> + if (ret < 0)
> + goto out;
> +
> + reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
> + reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
> + reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
> + QCA8K_VTU_FUNC0_EG_MODE_S(port);
> +
> + /* Check if we're the last member to be removed */
> + del = true;
> + for (i = 0; i < QCA8K_NUM_PORTS; i++) {
> + mask = QCA8K_VTU_FUNC0_EG_MODE_NOT;
> + mask <<= QCA8K_VTU_FUNC0_EG_MODE_S(i);
> +
> + if ((reg & mask) != mask) {
> + del = false;
> + break;
> + }
> + }
> +
> + if (del) {
> + ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
> + } else {
> + qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
> + ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
> + }
> +
> +out:
> + mutex_unlock(&priv->reg_mutex);
> +
> + return ret;
> +}
> +
> static void
> qca8k_mib_init(struct qca8k_priv *priv)
> {
> @@ -1187,6 +1293,76 @@ qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
> return 0;
> }
>
> +static int
> +qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering)
> +{
> + struct qca8k_priv *priv = ds->priv;
> +
> + if (vlan_filtering) {
> + qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
> + QCA8K_PORT_LOOKUP_VLAN_MODE,
> + QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
> + } else {
> + qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
> + QCA8K_PORT_LOOKUP_VLAN_MODE,
> + QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
> + }
> +
> + return 0;
> +}
> +
> +static int
> +qca8k_port_vlan_prepare(struct dsa_switch *ds, int port,
> + const struct switchdev_obj_port_vlan *vlan)
> +{
> + return 0;
> +}
> +
> +static void
> +qca8k_port_vlan_add(struct dsa_switch *ds, int port,
> + const struct switchdev_obj_port_vlan *vlan)
> +{
> + bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
> + bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
> + struct qca8k_priv *priv = ds->priv;
> + int ret = 0;
> + u16 vid;
> +
> + for (vid = vlan->vid_begin; vid <= vlan->vid_end && !ret; ++vid)
> + ret = qca8k_vlan_add(priv, port, vid, untagged);
> +
> + if (ret)
> + dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
> +
> + if (pvid) {
> + int shift = 16 * (port % 2);
> +
> + qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
> + 0xfff << shift,
> + vlan->vid_end << shift);
> + qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
> + QCA8K_PORT_VLAN_CVID(vlan->vid_end) |
> + QCA8K_PORT_VLAN_SVID(vlan->vid_end));
> + }
> +}
> +
> +static int
> +qca8k_port_vlan_del(struct dsa_switch *ds, int port,
> + const struct switchdev_obj_port_vlan *vlan)
> +{
> + struct qca8k_priv *priv = ds->priv;
> + int ret = 0;
> + u16 vid;
> +
> + for (vid = vlan->vid_begin; vid <= vlan->vid_end && !ret; ++vid)
> + ret = qca8k_vlan_del(priv, port, vid);
> +
> + if (ret)
> + dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
> +
> + return ret;
> +}
> +
> static enum dsa_tag_protocol
> qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
> enum dsa_tag_protocol mp)
> @@ -1212,6 +1388,10 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
> .port_fdb_add = qca8k_port_fdb_add,
> .port_fdb_del = qca8k_port_fdb_del,
> .port_fdb_dump = qca8k_port_fdb_dump,
> + .port_vlan_filtering = qca8k_port_vlan_filtering,
> + .port_vlan_prepare = qca8k_port_vlan_prepare,
> + .port_vlan_add = qca8k_port_vlan_add,
> + .port_vlan_del = qca8k_port_vlan_del,
> .phylink_validate = qca8k_phylink_validate,
> .phylink_mac_link_state = qca8k_phylink_mac_link_state,
> .phylink_mac_config = qca8k_phylink_mac_config,
> @@ -1262,6 +1442,7 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
>
> priv->ds->dev = &mdiodev->dev;
> priv->ds->num_ports = QCA8K_NUM_PORTS;
> + priv->ds->configure_vlan_while_not_filtering = true;
> priv->ds->priv = priv;
> priv->ops = qca8k_switch_ops;
> priv->ds->ops = &priv->ops;
> diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
> index 92216a52daa5..7ca4b93e0bb5 100644
> --- a/drivers/net/dsa/qca8k.h
> +++ b/drivers/net/dsa/qca8k.h
> @@ -128,6 +128,19 @@
> #define QCA8K_ATU_FUNC_FULL BIT(12)
> #define QCA8K_ATU_FUNC_PORT_M 0xf
> #define QCA8K_ATU_FUNC_PORT_S 8
> +#define QCA8K_REG_VTU_FUNC0 0x610
> +#define QCA8K_VTU_FUNC0_VALID BIT(20)
> +#define QCA8K_VTU_FUNC0_IVL_EN BIT(19)
> +#define QCA8K_VTU_FUNC0_EG_MODE_S(_i) (4 + (_i) * 2)
> +#define QCA8K_VTU_FUNC0_EG_MODE_MASK 3
> +#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD 0
> +#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG 1
> +#define QCA8K_VTU_FUNC0_EG_MODE_TAG 2
> +#define QCA8K_VTU_FUNC0_EG_MODE_NOT 3
> +#define QCA8K_REG_VTU_FUNC1 0x614
> +#define QCA8K_VTU_FUNC1_BUSY BIT(31)
> +#define QCA8K_VTU_FUNC1_VID_S 16
> +#define QCA8K_VTU_FUNC1_FULL BIT(4)
> #define QCA8K_REG_GLOBAL_FW_CTRL0 0x620
> #define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10)
> #define QCA8K_REG_GLOBAL_FW_CTRL1 0x624
> @@ -137,6 +150,11 @@
> #define QCA8K_GLOBAL_FW_CTRL1_UC_DP_S 0
> #define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc)
> #define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0)
> +#define QCA8K_PORT_LOOKUP_VLAN_MODE GENMASK(9, 8)
> +#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE (0 << 8)
> +#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK (1 << 8)
> +#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK (2 << 8)
> +#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE (3 << 8)
> #define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16)
> #define QCA8K_PORT_LOOKUP_STATE_DISABLED (0 << 16)
> #define QCA8K_PORT_LOOKUP_STATE_BLOCKING (1 << 16)
> @@ -180,6 +198,15 @@ enum qca8k_fdb_cmd {
> QCA8K_FDB_SEARCH = 7,
> };
>
> +enum qca8k_vlan_cmd {
> + QCA8K_VLAN_FLUSH = 1,
> + QCA8K_VLAN_LOAD = 2,
> + QCA8K_VLAN_PURGE = 3,
> + QCA8K_VLAN_REMOVE_PORT = 4,
> + QCA8K_VLAN_NEXT = 5,
> + QCA8K_VLAN_READ = 6,
> +};
> +
> struct ar8xxx_port_status {
> int enabled;
> };
> --
> 2.20.1
>
^ permalink raw reply
* Re: [PATCH net-next v3 1/2] net: dsa: qca8k: Add define for port VID
From: Vladimir Oltean @ 2020-08-02 13:21 UTC (permalink / raw)
To: Jonathan McDowell
Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David Miller,
Jakub Kicinski, Russell King - ARM Linux admin, Matthew Hagan,
netdev, linux-kernel
In-Reply-To: <08fd70c48668544408bdb7932ef23e13d1080ad1.1596301468.git.noodles@earth.li>
On Sat, Aug 01, 2020 at 06:05:54PM +0100, Jonathan McDowell wrote:
> Rather than using a magic value of 1 when configuring the port VIDs add
> a QCA8K_PORT_VID_DEF define and use that instead. Also fix up the
> bitmask in the process; the top 4 bits are reserved so this wasn't a
> problem, but only masking 12 bits is the correct approach.
>
> Signed-off-by: Jonathan McDowell <noodles@earth.li>
> ---
Acked-by: Vladimir Oltean <olteanv@gmail.com>
> drivers/net/dsa/qca8k.c | 11 ++++++-----
> drivers/net/dsa/qca8k.h | 2 ++
> 2 files changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> index a5566de82853..3ebc4da63074 100644
> --- a/drivers/net/dsa/qca8k.c
> +++ b/drivers/net/dsa/qca8k.c
> @@ -663,10 +663,11 @@ qca8k_setup(struct dsa_switch *ds)
> * default egress vid
> */
> qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
> - 0xffff << shift, 1 << shift);
> + 0xfff << shift,
> + QCA8K_PORT_VID_DEF << shift);
> qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
> - QCA8K_PORT_VLAN_CVID(1) |
> - QCA8K_PORT_VLAN_SVID(1));
> + QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
> + QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
> }
> }
>
> @@ -1133,7 +1134,7 @@ qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
> {
> /* Set the vid to the port vlan id if no vid is set */
> if (!vid)
> - vid = 1;
> + vid = QCA8K_PORT_VID_DEF;
>
> return qca8k_fdb_add(priv, addr, port_mask, vid,
> QCA8K_ATU_STATUS_STATIC);
> @@ -1157,7 +1158,7 @@ qca8k_port_fdb_del(struct dsa_switch *ds, int port,
> u16 port_mask = BIT(port);
>
> if (!vid)
> - vid = 1;
> + vid = QCA8K_PORT_VID_DEF;
>
> return qca8k_fdb_del(priv, addr, port_mask, vid);
> }
> diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
> index 31439396401c..92216a52daa5 100644
> --- a/drivers/net/dsa/qca8k.h
> +++ b/drivers/net/dsa/qca8k.h
> @@ -22,6 +22,8 @@
>
> #define QCA8K_CPU_PORT 0
>
> +#define QCA8K_PORT_VID_DEF 1
> +
> /* Global control registers */
> #define QCA8K_REG_MASK_CTRL 0x000
> #define QCA8K_MASK_CTRL_ID_M 0xff
> --
> 2.20.1
>
^ permalink raw reply
* Re:Re: [PATCH] soc: qmi: allow user to set handle wq to hiprio
From: 王文虎 @ 2020-08-02 13:14 UTC (permalink / raw)
To: Bjorn Andersson
Cc: elder, davem, kuba, kvalo, agross, ohad, linux-kernel,
linux-arm-msm, linux-remoteproc, alsa-devel, ath11k, netdev,
ath10k, linux-wireless, srinivas.kandagatla, sibis
In-Reply-To: <20200727204521.GB229995@builder.lan>
>> Currently the qmi_handle is initialized single threaded and strictly
>> ordered with the active set to 1. This is pretty simple and safe but
>> sometimes ineffency. So it is better to allow user to decide whether
>> a high priority workqueue should be used.
>
>Can you please describe a scenario where this is needed/desired and
>perhaps also comment on why this is not always desired?
>
Well, one scenario is that when the AP wants to check the status of the
subsystems and the whole QMI data path. It first sends out an indication
which asks the subsystems to report their status. After the subsystems send
responses to the AP, the responses then are queued on the workqueue of
the QMI handler. Actually the AP is configured to do the check in a specific
interval regularly. And it check the report counts within a specific delay after
it sends out the related indication. When the AP has been under a heavy
load for long, the reports are queue their without CPU resource to update
the report counts within the specific delay. As a result, the thread that checks
the report counts takes it misleadingly that the QMI data path or the subsystems
are crashed.
The patch can really resolve the problem mentioned abolve.
For narmal situations, it is enough to just use normal priority QMI workqueue.
>Regards,
>Bjorn
>
>>
>> Signed-off-by: Wang Wenhu <wenhu.wang@vivo.com>
>> ---
>> drivers/net/ipa/ipa_qmi.c | 4 ++--
>> drivers/net/wireless/ath/ath10k/qmi.c | 2 +-
>> drivers/net/wireless/ath/ath11k/qmi.c | 2 +-
>> drivers/remoteproc/qcom_sysmon.c | 2 +-
>> drivers/slimbus/qcom-ngd-ctrl.c | 4 ++--
>> drivers/soc/qcom/pdr_interface.c | 4 ++--
>> drivers/soc/qcom/qmi_interface.c | 9 +++++++--
>> include/linux/soc/qcom/qmi.h | 3 ++-
>> samples/qmi/qmi_sample_client.c | 4 ++--
>> 9 files changed, 20 insertions(+), 14 deletions(-)
^ permalink raw reply
* [PATCH] p54: avoid accessing the data mapped to streaming DMA
From: Jia-Ju Bai @ 2020-08-02 13:29 UTC (permalink / raw)
To: chunkeey, kvalo, davem, kuba
Cc: linux-wireless, netdev, linux-kernel, Jia-Ju Bai
In p54p_tx(), skb->data is mapped to streaming DMA on line 337:
mapping = pci_map_single(..., skb->data, ...);
Then skb->data is accessed on line 349:
desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
This access may cause data inconsistency between CPU cache and hardware.
To fix this problem, ((struct p54_hdr *)skb->data)->req_id is stored in
a local variable before DMA mapping, and then the driver accesses this
local variable instead of skb->data.
Signed-off-by: Jia-Ju Bai <baijiaju@tsinghua.edu.cn>
---
drivers/net/wireless/intersil/p54/p54pci.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intersil/p54/p54pci.c b/drivers/net/wireless/intersil/p54/p54pci.c
index 80ad0b7eaef4..f8c6027cab6b 100644
--- a/drivers/net/wireless/intersil/p54/p54pci.c
+++ b/drivers/net/wireless/intersil/p54/p54pci.c
@@ -329,10 +329,12 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
struct p54p_desc *desc;
dma_addr_t mapping;
u32 idx, i;
+ __le32 device_addr;
spin_lock_irqsave(&priv->lock, flags);
idx = le32_to_cpu(ring_control->host_idx[1]);
i = idx % ARRAY_SIZE(ring_control->tx_data);
+ device_addr = ((struct p54_hdr *)skb->data)->req_id;
mapping = pci_map_single(priv->pdev, skb->data, skb->len,
PCI_DMA_TODEVICE);
@@ -346,7 +348,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
desc = &ring_control->tx_data[i];
desc->host_addr = cpu_to_le32(mapping);
- desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
+ desc->device_addr = device_addr;
desc->len = cpu_to_le16(skb->len);
desc->flags = 0;
--
2.17.1
^ permalink raw reply related
* Re: [net-next PATCH] net: phy: mdio-mvusb: select MDIO_DEVRES in Kconfig
From: Andrew Lunn @ 2020-08-02 13:44 UTC (permalink / raw)
To: Bartosz Golaszewski, g
Cc: Florian Fainelli, Heiner Kallweit, Russell King, David S . Miller,
Jakub Kicinski, netdev, linux-kernel, Bartosz Golaszewski,
kernel test robot
In-Reply-To: <20200802074953.1529-1-brgl@bgdev.pl>
On Sun, Aug 02, 2020 at 09:49:53AM +0200, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>
> PHYLIB is not selected by the mvusb driver but it uses mdio devres
> helpers. Explicitly select MDIO_DEVRES in this driver's Kconfig entry.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Fixes: 1814cff26739 ("net: phy: add a Kconfig option for mdio_devres")
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox