From b76078df15935b54c353eb0461c95a6eaf73c7ca Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 8 May 2021 14:36:33 +0200 Subject: [PATCH 1/3] net: qca_spi: Avoid reading signature three times in a row There is no need to read the signature three times. So bail out in case the second check failed. Signed-off-by: Stefan Wahren Signed-off-by: David S. Miller --- drivers/net/ethernet/qualcomm/qca_spi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index ab9b02574a15..3e2a54c2fc83 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -506,6 +506,7 @@ qcaspi_qca7k_sync(struct qcaspi *qca, int event) if (signature != QCASPI_GOOD_SIGNATURE) { qca->sync = QCASPI_SYNC_UNKNOWN; netdev_dbg(qca->net_dev, "sync: got CPU on, but signature was invalid, restart\n"); + return; } else { /* ensure that the WRBUF is empty */ qcaspi_read_register(qca, SPI_REG_WRBUF_SPC_AVA, From 6e03f3ff29c1b479cd10cab0d1c4530bafad601c Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 8 May 2021 14:36:34 +0200 Subject: [PATCH 2/3] net: qca_spi: Avoid re-sync for single signature error Setting a new network key would cause a reset of the QCA7000. Usually the driver only notice the SPI interrupt and a single signature error. So avoid the whole re-sync process (possible packet loss, transmit queue stop and no carrier for at least 1 second) in this case. Signed-off-by: Stefan Wahren Signed-off-by: David S. Miller --- drivers/net/ethernet/qualcomm/qca_spi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index 3e2a54c2fc83..0937ceb08296 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -524,8 +524,11 @@ qcaspi_qca7k_sync(struct qcaspi *qca, int event) switch (qca->sync) { case QCASPI_SYNC_READY: - /* Read signature, if not valid go to unknown state. */ + /* Check signature twice, if not valid go to unknown state. */ qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature); + if (signature != QCASPI_GOOD_SIGNATURE) + qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature); + if (signature != QCASPI_GOOD_SIGNATURE) { qca->sync = QCASPI_SYNC_UNKNOWN; netdev_dbg(qca->net_dev, "sync: bad signature, restart\n"); From a53935674563f60d8e22ca88ab607dac89fb353d Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 8 May 2021 14:36:35 +0200 Subject: [PATCH 3/3] net: qca_spi: Introduce stat about bad signature In order to identify significant signature issues add a new stat counter, which increases on bad signature values that causes a sync loss. Signed-off-by: Stefan Wahren Signed-off-by: David S. Miller --- drivers/net/ethernet/qualcomm/qca_debug.c | 1 + drivers/net/ethernet/qualcomm/qca_spi.c | 4 ++++ drivers/net/ethernet/qualcomm/qca_spi.h | 1 + 3 files changed, 6 insertions(+) diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c b/drivers/net/ethernet/qualcomm/qca_debug.c index 702aa217a27a..d59fff2fbcc6 100644 --- a/drivers/net/ethernet/qualcomm/qca_debug.c +++ b/drivers/net/ethernet/qualcomm/qca_debug.c @@ -62,6 +62,7 @@ static const char qcaspi_gstrings_stats[][ETH_GSTRING_LEN] = { "SPI errors", "Write verify errors", "Buffer available errors", + "Bad signature", }; #ifdef CONFIG_DEBUG_FS diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index 0937ceb08296..79fe3ec4e581 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -504,6 +504,9 @@ qcaspi_qca7k_sync(struct qcaspi *qca, int event) qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature); qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature); if (signature != QCASPI_GOOD_SIGNATURE) { + if (qca->sync == QCASPI_SYNC_READY) + qca->stats.bad_signature++; + qca->sync = QCASPI_SYNC_UNKNOWN; netdev_dbg(qca->net_dev, "sync: got CPU on, but signature was invalid, restart\n"); return; @@ -531,6 +534,7 @@ qcaspi_qca7k_sync(struct qcaspi *qca, int event) if (signature != QCASPI_GOOD_SIGNATURE) { qca->sync = QCASPI_SYNC_UNKNOWN; + qca->stats.bad_signature++; netdev_dbg(qca->net_dev, "sync: bad signature, restart\n"); /* don't reset right away */ return; diff --git a/drivers/net/ethernet/qualcomm/qca_spi.h b/drivers/net/ethernet/qualcomm/qca_spi.h index d13a67e20d65..3067356106f0 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.h +++ b/drivers/net/ethernet/qualcomm/qca_spi.h @@ -75,6 +75,7 @@ struct qcaspi_stats { u64 spi_err; u64 write_verify_failed; u64 buf_avail_err; + u64 bad_signature; }; struct qcaspi {