All of lore.kernel.org
 help / color / mirror / Atom feed
* RFQ: wifi: wilc1000: make wilc1000-spi bus-probe useful
@ 2024-01-19 21:51 David Mosberger-Tang
  2024-01-22 14:19 ` Alexis Lothoré
  2024-01-22 16:57 ` Ajay.Kathat
  0 siblings, 2 replies; 29+ messages in thread
From: David Mosberger-Tang @ 2024-01-19 21:51 UTC (permalink / raw)
  To: Ajay.Kathat; +Cc: linux-wireless, kvalo

The current version of the wilc1000 driver has a probe function that simply
assumes the chip is present. It is only later, in wilc_spi_init(), that the
driver verifies that it can actually communicate with the chip. The result of
this is that the net device (typically wlan0) is created and remains in place as
long as the wilc1000-spi driver is loaded, even if the WILC1000 chip is not
present or not working.

Is there any reason not to detect the chip's present in wilc_bus_probe()? The
patch below (relative to 5.15.147) works for me, but perhaps I'm missing
something? Would it make sense to merge something along these lines into
mainline?

 --david

diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c
b/drivers/net/wireless/microchip/wilc1000/spi.c
index 6bac52527e38..c7ab816d65bc 100644
--- a/drivers/net/wireless/microchip/wilc1000/spi.c
+++ b/drivers/net/wireless/microchip/wilc1000/spi.c
@@ -42,7 +42,7 @@ MODULE_PARM_DESC(enable_crc16,
 #define WILC_SPI_RSP_HDR_EXTRA_DATA 8
 struct wilc_spi {
- bool isinit; /* true if SPI protocol has been configured */
+ bool isinit; /* true if wilc_spi_init was successful */
 bool probing_crc; /* true if we're probing chip's CRC config */
 bool crc7_enabled; /* true if crc7 is currently enabled */
 bool crc16_enabled; /* true if crc16 is currently enabled */
@@ -55,6 +55,7 @@ struct wilc_spi {
 static const struct wilc_hif_func wilc_hif_spi;
 static int wilc_spi_reset(struct wilc *wilc);
+static int wilc_spi_configure_bus_protocol(struct wilc *);
 /********************************************
 *
@@ -232,6 +233,22 @@ static int wilc_bus_probe(struct spi_device *spi)
 }
 clk_prepare_enable(wilc->rtc_clk);
+ dev_info(&spi->dev, "crc7=%sabled crc16=%sabled",
+ enable_crc7 ? "en" : "dis", enable_crc16 ? "en" : "dis");
+
+ /* we need power to configure the bus protocol and to read the chip id: */
+
+ wilc_wlan_power(wilc, true);
+
+ ret = wilc_spi_configure_bus_protocol(wilc);
+
+ wilc_wlan_power(wilc, false);
+
+ if (ret) {
+ ret = -ENODEV;
+ goto netdev_cleanup;
+ }
+
 return 0;
 netdev_cleanup:
@@ -1108,7 +1125,7 @@ static int wilc_spi_deinit(struct wilc *wilc)
 return 0;
 }
-static int wilc_spi_init(struct wilc *wilc, bool resume)
+static int wilc_spi_configure_bus_protocol (struct wilc *wilc)
 {
 struct spi_device *spi = to_spi_device(wilc->dev);
 struct wilc_spi *spi_priv = wilc->bus_data;
@@ -1116,21 +1133,6 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
 u32 chipid;
 int ret, i;
- if (spi_priv->isinit) {
- /* Confirm we can read chipid register without error: */
- ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
- if (ret == 0)
- return 0;
-
- dev_err(&spi->dev, "Fail cmd read chip id...\n");
- }
-
- wilc_wlan_power(wilc, true);
-
- /*
- * configure protocol
- */
-
 /*
 * Infer the CRC settings that are currently in effect. This
 * is necessary because we can't be sure that the chip has
@@ -1147,7 +1149,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
 }
 if (ret) {
 dev_err(&spi->dev, "Failed with CRC7 on and off.\n");
- goto fail;
+ return ret;
 }
 /* set up the desired CRC configuration: */
@@ -1170,7 +1172,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
 dev_err(&spi->dev,
 "[wilc spi %d]: Failed internal write reg\n",
 __LINE__);
- goto fail;
+ return ret;
 }
 /* update our state to match new protocol settings: */
 spi_priv->crc7_enabled = enable_crc7;
@@ -1187,16 +1189,38 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
 ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
 if (ret) {
 dev_err(&spi->dev, "Fail cmd read chip id...\n");
- goto fail;
+ return ret;
+ }
+ return 0;
+}
+
+static int wilc_spi_init(struct wilc *wilc, bool resume)
+{
+ struct spi_device *spi = to_spi_device(wilc->dev);
+ struct wilc_spi *spi_priv = wilc->bus_data;
+ u32 chipid;
+ int ret;
+
+ if (spi_priv->isinit) {
+ /* Confirm we can read chipid register without error: */
+ ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
+ if (ret == 0)
+ return 0;
+
+ dev_err(&spi->dev, "Fail cmd read chip id...\n");
+ }
+
+ wilc_wlan_power(wilc, true);
+
+ ret = wilc_spi_configure_bus_protocol(wilc);
+ if (ret) {
+ wilc_wlan_power(wilc, false);
+ return ret;
 }
 spi_priv->isinit = true;
 return 0;
-
- fail:
- wilc_wlan_power(wilc, false);
- return ret;
 }
 static int wilc_spi_read_size(struct wilc *wilc, u32 *size)


^ permalink raw reply related	[flat|nested] 29+ messages in thread
* [PATCH] wifi: wilc1000: validate chip id during bus probe
@ 2024-02-12 20:22 David Mosberger-Tang
  2024-02-13 14:52 ` Alexis Lothoré
  2024-02-15 11:09 ` Kalle Valo
  0 siblings, 2 replies; 29+ messages in thread
From: David Mosberger-Tang @ 2024-02-12 20:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ajay.Kathat, alexis.lothore, kvalo, David Mosberger-Tang

Previously, the driver created a net device (typically wlan0) as soon
as the module was loaded.  This commit changes the driver to follow
normal Linux convention of creating the net device only when bus
probing detects a supported chip.

Signed-off-by: David Mosberger-Tang <davidm@egauge.net>
---
changelog:
V1: original version
V2: Add missing forward declarations
V3: Add missing forward declarations, actually :-(
V4: - rearranged function order to improve readability
    - now relative to wireless-next repository
    - avoid change error return value and have lower-level functions
      directly return -ENODEV instead
    - removed any mention of WILC3000
    - export and use existing is_wilc1000() for chipid validation
    - replaced strbool() function with open code
V5: - add clk_disable_unprepare() to power_down path as suggested by Ajay
    - don't re-write error codes as suggested by Alexi
V6: - define is_wilc1000() as an inline function since it is trivial and
      does not warrant an EXPORT_SYMBOL_GPL() entry (suggested by Kalle)

 drivers/net/wireless/microchip/wilc1000/spi.c | 69 +++++++++++++++----
 .../net/wireless/microchip/wilc1000/wlan.c    |  5 --
 .../net/wireless/microchip/wilc1000/wlan.h    |  5 ++
 3 files changed, 59 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c
index c92ee4b73a74..3c4451535c8a 100644
--- a/drivers/net/wireless/microchip/wilc1000/spi.c
+++ b/drivers/net/wireless/microchip/wilc1000/spi.c
@@ -42,7 +42,7 @@ MODULE_PARM_DESC(enable_crc16,
 #define WILC_SPI_RSP_HDR_EXTRA_DATA	8
 
 struct wilc_spi {
-	bool isinit;		/* true if SPI protocol has been configured */
+	bool isinit;		/* true if wilc_spi_init was successful */
 	bool probing_crc;	/* true if we're probing chip's CRC config */
 	bool crc7_enabled;	/* true if crc7 is currently enabled */
 	bool crc16_enabled;	/* true if crc16 is currently enabled */
@@ -55,6 +55,8 @@ struct wilc_spi {
 static const struct wilc_hif_func wilc_hif_spi;
 
 static int wilc_spi_reset(struct wilc *wilc);
+static int wilc_spi_configure_bus_protocol(struct wilc *wilc);
+static int wilc_validate_chipid(struct wilc *wilc);
 
 /********************************************
  *
@@ -232,8 +234,27 @@ static int wilc_bus_probe(struct spi_device *spi)
 	}
 	clk_prepare_enable(wilc->rtc_clk);
 
+	dev_info(&spi->dev, "Selected CRC config: crc7=%s, crc16=%s\n",
+		 enable_crc7 ? "on" : "off", enable_crc16 ? "on" : "off");
+
+	/* we need power to configure the bus protocol and to read the chip id: */
+
+	wilc_wlan_power(wilc, true);
+
+	ret = wilc_spi_configure_bus_protocol(wilc);
+	if (ret)
+		goto power_down;
+
+	ret = wilc_validate_chipid(wilc);
+	if (ret)
+		goto power_down;
+
+	wilc_wlan_power(wilc, false);
 	return 0;
 
+power_down:
+	clk_disable_unprepare(wilc->rtc_clk);
+	wilc_wlan_power(wilc, false);
 netdev_cleanup:
 	wilc_netdev_cleanup(wilc);
 free:
@@ -1102,26 +1123,34 @@ static int wilc_spi_deinit(struct wilc *wilc)
 
 static int wilc_spi_init(struct wilc *wilc, bool resume)
 {
-	struct spi_device *spi = to_spi_device(wilc->dev);
 	struct wilc_spi *spi_priv = wilc->bus_data;
-	u32 reg;
-	u32 chipid;
-	int ret, i;
+	int ret;
 
 	if (spi_priv->isinit) {
 		/* Confirm we can read chipid register without error: */
-		ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
-		if (ret == 0)
+		if (wilc_validate_chipid(wilc) == 0)
 			return 0;
-
-		dev_err(&spi->dev, "Fail cmd read chip id...\n");
 	}
 
 	wilc_wlan_power(wilc, true);
 
-	/*
-	 * configure protocol
-	 */
+	ret = wilc_spi_configure_bus_protocol(wilc);
+	if (ret) {
+		wilc_wlan_power(wilc, false);
+		return ret;
+	}
+
+	spi_priv->isinit = true;
+
+	return 0;
+}
+
+static int wilc_spi_configure_bus_protocol(struct wilc *wilc)
+{
+	struct spi_device *spi = to_spi_device(wilc->dev);
+	struct wilc_spi *spi_priv = wilc->bus_data;
+	u32 reg;
+	int ret, i;
 
 	/*
 	 * Infer the CRC settings that are currently in effect.  This
@@ -1173,6 +1202,15 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
 
 	spi_priv->probing_crc = false;
 
+	return 0;
+}
+
+static int wilc_validate_chipid(struct wilc *wilc)
+{
+	struct spi_device *spi = to_spi_device(wilc->dev);
+	u32 chipid;
+	int ret;
+
 	/*
 	 * make sure can read chip id without protocol error
 	 */
@@ -1181,9 +1219,10 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
 		dev_err(&spi->dev, "Fail cmd read chip id...\n");
 		return ret;
 	}
-
-	spi_priv->isinit = true;
-
+	if (!is_wilc1000(chipid)) {
+		dev_err(&spi->dev, "Unknown chip id 0x%x\n", chipid);
+		return -ENODEV;
+	}
 	return 0;
 }
 
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c
index 6b2f2269ddf8..68be233c36ce 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.c
@@ -12,11 +12,6 @@
 
 #define WAKE_UP_TRIAL_RETRY		10000
 
-static inline bool is_wilc1000(u32 id)
-{
-	return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
-}
-
 static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
 {
 	mutex_lock(&wilc->hif_cs);
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h
index f02775f7e41f..54643d8fef04 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan.h
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.h
@@ -409,6 +409,11 @@ struct wilc_cfg_rsp {
 
 struct wilc_vif;
 
+static inline bool is_wilc1000(u32 id)
+{
+	return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
+}
+
 int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
 				u32 buffer_size);
 int wilc_wlan_start(struct wilc *wilc);
-- 
2.34.1


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

end of thread, other threads:[~2024-02-15 11:09 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-19 21:51 RFQ: wifi: wilc1000: make wilc1000-spi bus-probe useful David Mosberger-Tang
2024-01-22 14:19 ` Alexis Lothoré
2024-01-22 20:41   ` David Mosberger-Tang
2024-01-22 21:13     ` David Mosberger-Tang
2024-01-22 21:13       ` [PATCH] wifi: wilc1000: validate chip id during bus probe David Mosberger-Tang
2024-01-22 22:01         ` David Mosberger-Tang
2024-01-22 22:03         ` David Mosberger-Tang
2024-01-23 10:18           ` Alexis Lothoré
2024-01-23 11:06             ` Kalle Valo
2024-01-23 12:44               ` Alexis Lothoré
2024-01-23 12:59                 ` Kalle Valo
2024-01-23 13:29                   ` Alexis Lothoré
2024-01-23 17:39             ` David Mosberger-Tang
2024-01-24  9:01               ` Alexis Lothoré
2024-01-24 16:15                 ` David Mosberger-Tang
2024-01-24 17:31                 ` David Mosberger-Tang
2024-01-24 18:45                   ` David Mosberger-Tang
2024-01-25  6:23                     ` Ajay.Kathat
2024-01-25 11:04                       ` Alexis Lothoré
2024-01-25 17:15                         ` Ajay.Kathat
2024-01-25 19:17                         ` David Mosberger-Tang
2024-01-23  9:16     ` RFQ: wifi: wilc1000: make wilc1000-spi bus-probe useful Alexis Lothoré
2024-01-23  9:28       ` Kalle Valo
2024-01-22 16:57 ` Ajay.Kathat
2024-01-22 20:44   ` David Mosberger-Tang
2024-01-23  6:31   ` Kalle Valo
  -- strict thread matches above, loose matches on Subject: below --
2024-02-12 20:22 [PATCH] wifi: wilc1000: validate chip id during bus probe David Mosberger-Tang
2024-02-13 14:52 ` Alexis Lothoré
2024-02-15 11:09 ` Kalle Valo

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.