From 7653aa5eac530ca598e2ed44b32562d1c52b6f83 Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Sun, 17 Dec 2023 08:01:11 +0100 Subject: [PATCH 01/24] wilc1000: fix possible access to NULL value (from upstream) --- drivers/staging/wilc1000/netdev.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index 3e7aff7af36daf..d51b4247fa2444 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -744,14 +744,15 @@ static void wilc_wlan_deinitialize(struct net_device *dev) struct wilc_vif *vif = netdev_priv(dev); struct wilc *wl = vif->wilc; + if (!wl) { + PRINT_ER(dev, "wl is NULL\n"); + return; + } + + if (wl->initialized) { PRINT_INFO(vif->ndev, INIT_DBG, "Deinitializing wilc ...\n"); - if (!wl) { - PRINT_ER(dev, "wl is NULL\n"); - return; - } - PRINT_D(vif->ndev, INIT_DBG, "destroy aging timer\n"); PRINT_INFO(vif->ndev, INIT_DBG, "Disabling IRQ\n"); From f542495b3fcd4ec489ef4a7ce65ad717f56814c4 Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Sun, 17 Dec 2023 08:02:05 +0100 Subject: [PATCH 02/24] wilc: make hw mac structure aligned to prevent sporadic bus error (from newer upstream) --- drivers/staging/wilc1000/netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index d51b4247fa2444..80d9b35b918f46 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -929,7 +929,7 @@ static int wilc_mac_open(struct net_device *ndev) { struct wilc_vif *vif = netdev_priv(ndev); struct wilc *wl = vif->wilc; - unsigned char mac_add[ETH_ALEN] = {0}; + unsigned char mac_add[ETH_ALEN] __aligned(2) = { 0 }; int ret = 0; if (!wl || !wl->dev) { @@ -1000,7 +1000,7 @@ static int wilc_set_mac_addr(struct net_device *dev, void *p) struct wilc_vif *vif = netdev_priv(dev); struct sockaddr *addr = (struct sockaddr *)p; struct wilc *wilc = vif->wilc; - unsigned char mac_addr[6] = {0}; + unsigned char mac_addr[6] __aligned(2) = { 0 }; struct wilc_vif *tmp_vif; int srcu_idx; From 9c2aa708f8e46482ef74cfc8c33f101a890e66f2 Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Sun, 17 Dec 2023 08:03:42 +0100 Subject: [PATCH 03/24] wilc: minor fix to identation to make logic more understandable --- drivers/staging/wilc1000/netdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index 80d9b35b918f46..1eb3fdcc48f858 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -1165,10 +1165,10 @@ static int wilc_mac_close(struct net_device *ndev) if (vif->ndev) { netif_stop_queue(vif->ndev); - handle_connect_cancel(vif); + handle_connect_cancel(vif); - if (!recovery_on) - wilc_deinit_host_int(vif->ndev); + if (!recovery_on) + wilc_deinit_host_int(vif->ndev); } if (wl->open_ifcs == 0) { From 173c73bba33827ffb71f7294ab15d538e3982744 Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Sun, 17 Dec 2023 08:04:46 +0100 Subject: [PATCH 04/24] wilc: fix possible double free (from upstream) --- drivers/staging/wilc1000/netdev.c | 1 - drivers/staging/wilc1000/sdio.c | 2 ++ drivers/staging/wilc1000/spi.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index 1eb3fdcc48f858..dc6872fe66e711 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -1267,7 +1267,6 @@ void wilc_netdev_cleanup(struct wilc *wilc) #endif wilc_sysfs_exit(); wlan_deinit_locks(wilc); - kfree(wilc->bus_data); wiphy_unregister(wilc->wiphy); pr_info("Freeing wiphy\n"); wiphy_free(wilc->wiphy); diff --git a/drivers/staging/wilc1000/sdio.c b/drivers/staging/wilc1000/sdio.c index 90be674a77d029..3235ac6357688c 100644 --- a/drivers/staging/wilc1000/sdio.c +++ b/drivers/staging/wilc1000/sdio.c @@ -227,12 +227,14 @@ static int wilc_sdio_probe(struct sdio_func *func, static void wilc_sdio_remove(struct sdio_func *func) { struct wilc *wilc = sdio_get_drvdata(func); + struct wilc_sdio *sdio_priv = wilc->bus_data; if (!IS_ERR(wilc->rtc_clk)) clk_disable_unprepare(wilc->rtc_clk); wilc_netdev_cleanup(wilc); wilc_bt_deinit(); + kfree(sdio_priv); } static int wilc_sdio_reset(struct wilc *wilc) diff --git a/drivers/staging/wilc1000/spi.c b/drivers/staging/wilc1000/spi.c index 634454a00a713e..84e0818a77b211 100644 --- a/drivers/staging/wilc1000/spi.c +++ b/drivers/staging/wilc1000/spi.c @@ -168,12 +168,14 @@ static int wilc_bus_probe(struct spi_device *spi) static int wilc_bus_remove(struct spi_device *spi) { struct wilc *wilc = spi_get_drvdata(spi); + struct wilc_spi *spi_priv = wilc->bus_data; if (!IS_ERR(wilc->rtc_clk)) clk_disable_unprepare(wilc->rtc_clk); wilc_netdev_cleanup(wilc); wilc_bt_deinit(); + kfree(spi_priv); return 0; } From 7946d3190eda9a9e4661ba4ec763d3cfe8dc9947 Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Sun, 17 Dec 2023 08:06:03 +0100 Subject: [PATCH 05/24] wilc: add small delay when waking up chip (from upstream) --- drivers/staging/wilc1000/wlan.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wlan.c b/drivers/staging/wilc1000/wlan.c index d603cd6cb6561c..c45eb096b61a1b 100644 --- a/drivers/staging/wilc1000/wlan.c +++ b/drivers/staging/wilc1000/wlan.c @@ -885,9 +885,12 @@ static void chip_wakeup_wilc3000(struct wilc *wilc, int source) /* in case of failure, Reset the wakeup bit to introduce a new * edge on the next loop */ - if ((clk_status_reg_val & clk_status_bit) == 0) + if ((clk_status_reg_val & clk_status_bit) == 0) { hif_func->hif_write_reg(wilc, wakeup_reg, wakeup_reg_val & (~wakeup_bit)); + /* added wait before wakeup sequence retry */ + usleep_range(200, 300); + } } while (((clk_status_reg_val & clk_status_bit) == 0) && (wake_seq_trials-- > 0)); if (!wake_seq_trials) @@ -1261,10 +1264,10 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count) out_release_bus: release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP, DEV_WIFI); - schedule(); out_unlock: mutex_unlock(&wilc->txq_add_to_head_cs); + schedule(); out_update_cnt: *txq_count = wilc->txq_entries; From 576b99d604cbb1ce0a6769bb75684d9a77c6a151 Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Sun, 17 Dec 2023 08:07:29 +0100 Subject: [PATCH 06/24] wilc: skip isr if in closing stage (from upstream) --- drivers/staging/wilc1000/wlan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/wilc1000/wlan.c b/drivers/staging/wilc1000/wlan.c index c45eb096b61a1b..b40cb74660d55f 100644 --- a/drivers/staging/wilc1000/wlan.c +++ b/drivers/staging/wilc1000/wlan.c @@ -1421,6 +1421,9 @@ void wilc_handle_isr(struct wilc *wilc) { u32 int_status; + if (wilc->close) + return; + acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP, DEV_WIFI); wilc->hif_func->hif_read_int(wilc, &int_status); From 07058badbadd13c523098439e9cf7f11c91d92ab Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Sun, 17 Dec 2023 08:08:07 +0100 Subject: [PATCH 07/24] wilc: on error do not allow going to sleep (from upstream) --- drivers/staging/wilc1000/wlan.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/wlan.c b/drivers/staging/wilc1000/wlan.c index b40cb74660d55f..f595684e2f5369 100644 --- a/drivers/staging/wilc1000/wlan.c +++ b/drivers/staging/wilc1000/wlan.c @@ -1570,7 +1570,7 @@ int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif) ret = wilc->hif_func->hif_read_reg(wilc, GLOBAL_MODE_CONTROL, ®); if (ret) { PRINT_ER(vif->ndev, "Error while reading reg\n"); - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP, DEV_WIFI); + release_bus(wilc, WILC_BUS_RELEASE_ONLY, DEV_WIFI); return -EIO; } @@ -1578,7 +1578,7 @@ int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif) ret = wilc->hif_func->hif_write_reg(wilc, GLOBAL_MODE_CONTROL, reg); if (ret) { PRINT_ER(vif->ndev, "Error while writing reg\n"); - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP, DEV_WIFI); + release_bus(wilc, WILC_BUS_RELEASE_ONLY, DEV_WIFI); return -EIO; } @@ -1588,7 +1588,7 @@ int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif) ret = wilc->hif_func->hif_read_reg(wilc, PWR_SEQ_MISC_CTRL, ®); if (ret) { PRINT_ER(vif->ndev, "Error while reading reg\n"); - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP, DEV_WIFI); + release_bus(wilc, WILC_BUS_RELEASE_ONLY, DEV_WIFI); return ret; } @@ -1596,14 +1596,14 @@ int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif) ret = wilc->hif_func->hif_write_reg(wilc, PWR_SEQ_MISC_CTRL, reg); if (ret) { PRINT_ER(vif->ndev, "Error while writing reg\n"); - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP, DEV_WIFI); + release_bus(wilc, WILC_BUS_RELEASE_ONLY, DEV_WIFI); return ret; } ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, ®); if (ret) { PRINT_ER(vif->ndev, "Error while reading reg\n"); - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP, DEV_WIFI); + release_bus(wilc, WILC_BUS_RELEASE_ONLY, DEV_WIFI); return ret; } @@ -1611,11 +1611,11 @@ int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif) (reg | WILC_ABORT_REQ_BIT)); if (ret) { PRINT_ER(vif->ndev, "Error while writing reg\n"); - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP, DEV_WIFI); + release_bus(wilc, WILC_BUS_RELEASE_ONLY, DEV_WIFI); return ret; } - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP, DEV_WIFI); + release_bus(wilc, WILC_BUS_RELEASE_ONLY, DEV_WIFI); return 0; } From c9e5d5fb2bc7ef2c17edfa4aa167534a4cc6e7a8 Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Sun, 17 Dec 2023 08:08:35 +0100 Subject: [PATCH 08/24] wilc: slight readapt of cleanup logic on error (partially from upstream) --- drivers/staging/wilc1000/netdev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index dc6872fe66e711..56a949af929c7e 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -872,9 +872,11 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) ret = wilc_start_firmware(dev); if (ret) { PRINT_ER(dev, "Failed to start firmware\n"); - goto fail_irq_enable; + goto fail_fw_start; } + wl->initialized = true; + if (cfg_get(vif, 1, WID_FIRMWARE_VERSION, 1, 0)) { int size; char firmware_ver[50]; @@ -894,7 +896,6 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) goto fail_fw_start; } - wl->initialized = true; return 0; fail_fw_start: From 461c435575075767c2d45d5c081d51c81ea6faa9 Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Sun, 17 Dec 2023 11:44:17 +0100 Subject: [PATCH 09/24] wilc: add a waiting period especially on deinit Albeit very "by tentative" this seems to leave time to the firmware to settle so we get less annoying problems if we redo an initialization shortly after. --- drivers/staging/wilc1000/netdev.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index 56a949af929c7e..98835b43231804 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -13,12 +13,17 @@ #include #include #include +#include #include "netdev.h" #include "cfg80211.h" #define WILC_MULTICAST_TABLE_SIZE 8 +#define INIT_TIMEOUT 300 +#define DEINIT_TIMEOUT 10000 + + static int wilc_mac_open(struct net_device *ndev); static int wilc_mac_close(struct net_device *ndev); @@ -786,6 +791,10 @@ static void wilc_wlan_deinitialize(struct net_device *dev) } else { PRINT_INFO(dev, INIT_DBG, "wilc is not initialized\n"); } + + pr_info("%s: Will sleep a bit after deinitialize\n", __func__); + msleep(DEINIT_TIMEOUT); + } static int wlan_initialize_threads(struct net_device *dev) @@ -827,6 +836,9 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) int ret = 0; struct wilc *wl = vif->wilc; + pr_info("%s: Will sleep a bit before initialize\n", __func__); + msleep(INIT_TIMEOUT); + if (!wl->initialized) { wl->mac_status = WILC_MAC_STATUS_INIT; wl->close = 0; From 7f4f22de21da79cc3ea8d52944075ef0ccdf33ba Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Mon, 18 Dec 2023 14:35:30 +0100 Subject: [PATCH 10/24] nulling bus_data when freeing sdio_priv --- drivers/staging/wilc1000/sdio.c | 2 ++ drivers/staging/wilc1000/spi.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/staging/wilc1000/sdio.c b/drivers/staging/wilc1000/sdio.c index 3235ac6357688c..2ccd80e0d948a2 100644 --- a/drivers/staging/wilc1000/sdio.c +++ b/drivers/staging/wilc1000/sdio.c @@ -221,6 +221,7 @@ static int wilc_sdio_probe(struct sdio_func *func, wilc_netdev_cleanup(wilc); free: kfree(sdio_priv); + wilc->bus_data = NULL; return ret; } @@ -235,6 +236,7 @@ static void wilc_sdio_remove(struct sdio_func *func) wilc_netdev_cleanup(wilc); wilc_bt_deinit(); kfree(sdio_priv); + wilc->bus_data = NULL; } static int wilc_sdio_reset(struct wilc *wilc) diff --git a/drivers/staging/wilc1000/spi.c b/drivers/staging/wilc1000/spi.c index 84e0818a77b211..737fe64a2b282a 100644 --- a/drivers/staging/wilc1000/spi.c +++ b/drivers/staging/wilc1000/spi.c @@ -162,6 +162,7 @@ static int wilc_bus_probe(struct spi_device *spi) wilc_netdev_cleanup(wilc); free: kfree(spi_priv); + wilc->bus_data = NULL; return ret; } @@ -176,6 +177,7 @@ static int wilc_bus_remove(struct spi_device *spi) wilc_netdev_cleanup(wilc); wilc_bt_deinit(); kfree(spi_priv); + wilc->bus_data = NULL; return 0; } From f2c69ccee8cc83c8a2d16fe053e775d2f996c3fa Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Tue, 19 Dec 2023 09:53:50 +0100 Subject: [PATCH 11/24] added some error check --- drivers/staging/wilc1000/sdio.c | 45 ++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wilc1000/sdio.c b/drivers/staging/wilc1000/sdio.c index 2ccd80e0d948a2..9218683974b957 100644 --- a/drivers/staging/wilc1000/sdio.c +++ b/drivers/staging/wilc1000/sdio.c @@ -261,6 +261,9 @@ static int wilc_sdio_reset(struct wilc *wilc) static bool wilc_sdio_is_init(struct wilc *wilc) { struct wilc_sdio *sdio_priv = wilc->bus_data; + if (!sdio_priv) { + return false; + } return sdio_priv->is_init; } @@ -412,6 +415,11 @@ static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + if (!sdio_priv) { + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + return -1; + } + int ret; cpu_to_le32s(&data); @@ -463,6 +471,11 @@ static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + if (!sdio_priv) { + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + return -1; + } + u32 block_size = sdio_priv->block_size; struct sdio_cmd53 cmd; int nblk, nleft, ret; @@ -536,6 +549,10 @@ static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + if (!sdio_priv) { + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + return -1; + } int ret; if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */ @@ -584,6 +601,10 @@ static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + if (!sdio_priv) { + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + return -1; + } u32 block_size = sdio_priv->block_size; struct sdio_cmd53 cmd; int nblk, nleft, ret; @@ -664,7 +685,9 @@ static int wilc_sdio_deinit(struct wilc *wilc) struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; - sdio_priv->is_init = false; + if (sdio_priv) { + sdio_priv->is_init = false; + } pm_runtime_put_sync_autosuspend(mmc_dev(func->card->host)); wilc_wlan_power(wilc, false); @@ -676,6 +699,11 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + if (!sdio_priv) { + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + return -1; + } + struct sdio_cmd52 cmd; int loop, ret; u32 chipid; @@ -834,6 +862,11 @@ static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + if (!sdio_priv) { + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + return -1; + } + u32 tmp; struct sdio_cmd52 cmd; u32 irq_flags; @@ -883,6 +916,11 @@ static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + if (!sdio_priv) { + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + return -1; + } + int ret; u32 reg = 0; @@ -974,6 +1012,11 @@ static int wilc_sdio_sync_ext(struct wilc *wilc, int nint) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + if (!sdio_priv) { + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + return -1; + } + u32 reg; int ret, i; From bcf9e8d84caa8087fd4ba430abb54cbe87194233 Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Tue, 19 Dec 2023 10:28:36 +0100 Subject: [PATCH 12/24] fix build issues --- drivers/staging/wilc1000/sdio.c | 37 ++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/staging/wilc1000/sdio.c b/drivers/staging/wilc1000/sdio.c index 9218683974b957..7debf403dc35bf 100644 --- a/drivers/staging/wilc1000/sdio.c +++ b/drivers/staging/wilc1000/sdio.c @@ -415,13 +415,13 @@ static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + int ret; + if (!sdio_priv) { - dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __func__); return -1; } - int ret; - cpu_to_le32s(&data); if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */ @@ -472,7 +472,7 @@ static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; if (!sdio_priv) { - dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __func__); return -1; } @@ -549,11 +549,12 @@ static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + int ret; + if (!sdio_priv) { - dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __func__); return -1; } - int ret; if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */ struct sdio_cmd52 cmd; @@ -601,13 +602,15 @@ static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + struct sdio_cmd53 cmd; + int nblk, nleft, ret; + u32 block_size; + if (!sdio_priv) { - dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __func__); return -1; } - u32 block_size = sdio_priv->block_size; - struct sdio_cmd53 cmd; - int nblk, nleft, ret; + block_size = sdio_priv->block_size; cmd.read_write = 0; if (addr > 0) { @@ -700,7 +703,7 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume) struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; if (!sdio_priv) { - dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __func__); return -1; } @@ -863,7 +866,7 @@ static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status) struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; if (!sdio_priv) { - dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __func__); return -1; } @@ -916,14 +919,14 @@ static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; + int ret; + u32 reg = 0; + if (!sdio_priv) { - dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __func__); return -1; } - int ret; - u32 reg = 0; - if (wilc->chip == WILC_1000) { if (sdio_priv->irq_gpio) reg = val & (BIT(MAX_NUM_INT) - 1); @@ -1013,7 +1016,7 @@ static int wilc_sdio_sync_ext(struct wilc *wilc, int nint) struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; if (!sdio_priv) { - dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __FUNC__); + dev_err(&func->dev, "%s: 'bus_data' not initialized\n", __func__); return -1; } From 3a1d70f601551341d19f353e19d2e27a4d0b8628 Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Tue, 19 Dec 2023 13:00:17 +0100 Subject: [PATCH 13/24] avoid errors on RSSI if driver has not yet been initialized --- drivers/staging/wilc1000/hif.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/wilc1000/hif.c b/drivers/staging/wilc1000/hif.c index 8d9cbc07af52b2..5389430a9ed291 100644 --- a/drivers/staging/wilc1000/hif.c +++ b/drivers/staging/wilc1000/hif.c @@ -1819,12 +1819,18 @@ int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level) { struct wid wid; int result; + struct wilc *wilc = vif->wilc; if (!rssi_level) { PRINT_ER(vif->ndev, "RSS pointer value is null\n"); return -EFAULT; } + if (!wilc->initialized) { + netdev_info(vif->ndev, "Driver not initialized\n"); + return 0; + } + wid.id = WID_RSSI; wid.type = WID_CHAR; wid.size = sizeof(char); From c2ff900217c6c83dfeaa11b60ed54e557345c9a0 Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Tue, 19 Dec 2023 17:35:32 +0100 Subject: [PATCH 14/24] added missing reset options (not sure they're really really needed) --- drivers/staging/wilc1000/netdev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index 98835b43231804..ec90229dc8379b 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -786,6 +786,8 @@ static void wilc_wlan_deinitialize(struct net_device *dev) wilc_wlan_cleanup(dev); wl->initialized = false; + wl->close = 0; + wl->quit = 0; PRINT_INFO(dev, INIT_DBG, "wilc deinitialization Done\n"); } else { @@ -842,6 +844,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) if (!wl->initialized) { wl->mac_status = WILC_MAC_STATUS_INIT; wl->close = 0; + wl->quit = 0; wl->initialized = 0; ret = wilc_wlan_init(dev); From 2187e89f0fe2a1189c4a214f5102800c54f3a660 Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Tue, 19 Dec 2023 17:36:04 +0100 Subject: [PATCH 15/24] added wilc powerdown on deinit --- drivers/staging/wilc1000/netdev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index ec90229dc8379b..af5411d1901e29 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -1192,6 +1192,9 @@ static int wilc_mac_close(struct net_device *ndev) wl->close = 1; wilc_wlan_deinitialize(ndev); + + PRINT_INFO(ndev, GENERIC_DBG, "Powering down wilc\n"); + wilc_bt_power_down(wl, DEV_WIFI); } vif->mac_opened = 0; From 27b6b66280e7f863304989c9d544fe571299ddea Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Tue, 19 Dec 2023 17:37:13 +0100 Subject: [PATCH 16/24] removed sleeps --- drivers/staging/wilc1000/netdev.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index af5411d1901e29..65f219cc4bbb45 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -20,10 +20,6 @@ #define WILC_MULTICAST_TABLE_SIZE 8 -#define INIT_TIMEOUT 300 -#define DEINIT_TIMEOUT 10000 - - static int wilc_mac_open(struct net_device *ndev); static int wilc_mac_close(struct net_device *ndev); @@ -793,10 +789,6 @@ static void wilc_wlan_deinitialize(struct net_device *dev) } else { PRINT_INFO(dev, INIT_DBG, "wilc is not initialized\n"); } - - pr_info("%s: Will sleep a bit after deinitialize\n", __func__); - msleep(DEINIT_TIMEOUT); - } static int wlan_initialize_threads(struct net_device *dev) @@ -838,9 +830,6 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) int ret = 0; struct wilc *wl = vif->wilc; - pr_info("%s: Will sleep a bit before initialize\n", __func__); - msleep(INIT_TIMEOUT); - if (!wl->initialized) { wl->mac_status = WILC_MAC_STATUS_INIT; wl->close = 0; From 9dd7b23815f3610331dd6403d35167a43de1c6fa Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Sat, 30 Oct 2021 11:20:09 +0200 Subject: [PATCH 17/24] %% original patch: 0001-Disable_noisy_WILC1000.patch --- drivers/staging/wilc1000/debugfs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wilc1000/debugfs.c b/drivers/staging/wilc1000/debugfs.c index 132066f3a8c902..8278e460409a54 100644 --- a/drivers/staging/wilc1000/debugfs.c +++ b/drivers/staging/wilc1000/debugfs.c @@ -9,9 +9,8 @@ #include "debugfs.h" -atomic_t WILC_DEBUG_REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | - CFG80211_DBG | HOSTAPD_DBG | - PWRDEV_DBG); +atomic_t WILC_DEBUG_REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG | HOSTAPD_DBG | PWRDEV_DBG | CORECONFIG_DBG); + #if KERNEL_VERSION(3, 15, 0) > LINUX_VERSION_CODE /** * of_irq_parse_raw - Low level interrupt tree parsing From a4acb1c4e52451feba9db5d4520b2508b68a5f2f Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Wed, 20 Dec 2023 11:23:28 +0100 Subject: [PATCH 18/24] Revert "%% original patch: 0001-Disable_noisy_WILC1000.patch" This reverts commit 9dd7b23815f3610331dd6403d35167a43de1c6fa. --- drivers/staging/wilc1000/debugfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/debugfs.c b/drivers/staging/wilc1000/debugfs.c index 8278e460409a54..132066f3a8c902 100644 --- a/drivers/staging/wilc1000/debugfs.c +++ b/drivers/staging/wilc1000/debugfs.c @@ -9,8 +9,9 @@ #include "debugfs.h" -atomic_t WILC_DEBUG_REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG | HOSTAPD_DBG | PWRDEV_DBG | CORECONFIG_DBG); - +atomic_t WILC_DEBUG_REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | + CFG80211_DBG | HOSTAPD_DBG | + PWRDEV_DBG); #if KERNEL_VERSION(3, 15, 0) > LINUX_VERSION_CODE /** * of_irq_parse_raw - Low level interrupt tree parsing From 96103b225ac09843f3ac20d4e3aaa140f1d916f1 Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Wed, 20 Dec 2023 15:05:52 +0100 Subject: [PATCH 19/24] added reset for `wilc->close` --- drivers/staging/wilc1000/wlan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/wilc1000/wlan.c b/drivers/staging/wilc1000/wlan.c index f595684e2f5369..1be3024eeb10f6 100644 --- a/drivers/staging/wilc1000/wlan.c +++ b/drivers/staging/wilc1000/wlan.c @@ -1889,6 +1889,7 @@ int wilc_wlan_init(struct net_device *dev) wilc = vif->wilc; wilc->quit = 0; + wilc->close = 0; PRINT_INFO(vif->ndev, INIT_DBG, "Initializing WILC_Wlan\n"); From 49e255888d37d8b6bdfecc936efeaace23e1a2cb Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Wed, 3 Jan 2024 12:38:40 +0100 Subject: [PATCH 20/24] removed duplicated property init (already in wilc_wlan_init) --- drivers/staging/wilc1000/netdev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index 65f219cc4bbb45..7a3adee2a56a94 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -832,9 +832,6 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) if (!wl->initialized) { wl->mac_status = WILC_MAC_STATUS_INIT; - wl->close = 0; - wl->quit = 0; - wl->initialized = 0; ret = wilc_wlan_init(dev); if (ret) { From 634bae86188b3e4ad936d25a6dd3f1cb9890d929 Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Fri, 5 Jan 2024 11:23:41 +0100 Subject: [PATCH 21/24] CHECK: wilc_wlan_deinitialize now respects the order of operations as in the initialize --- drivers/staging/wilc1000/netdev.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index 7a3adee2a56a94..6963a1b70e9880 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -750,10 +750,13 @@ static void wilc_wlan_deinitialize(struct net_device *dev) return; } - if (wl->initialized) { PRINT_INFO(vif->ndev, INIT_DBG, "Deinitializing wilc ...\n"); + ret = wilc_wlan_stop(wl, vif); + if (ret != 0) + PRINT_ER(dev, "failed in wlan_stop\n"); + PRINT_D(vif->ndev, INIT_DBG, "destroy aging timer\n"); PRINT_INFO(vif->ndev, INIT_DBG, "Disabling IRQ\n"); @@ -767,16 +770,11 @@ static void wilc_wlan_deinitialize(struct net_device *dev) mutex_unlock(&wl->hif_cs); } } - complete(&wl->txq_event); + deinit_irq(dev); PRINT_INFO(vif->ndev, INIT_DBG, "Deinitializing Threads\n"); wlan_deinitialize_threads(dev); PRINT_INFO(vif->ndev, INIT_DBG, "Deinitializing IRQ\n"); - deinit_irq(dev); - - ret = wilc_wlan_stop(wl, vif); - if (ret != 0) - PRINT_ER(dev, "failed in wlan_stop\n"); PRINT_INFO(vif->ndev, INIT_DBG, "Deinitializing WILC Wlan\n"); wilc_wlan_cleanup(dev); From b3c730b927970df7ab8a1315beeb0e545d54d2fa Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Fri, 5 Jan 2024 11:27:20 +0100 Subject: [PATCH 22/24] CHECK: the wilc->initialized flag should be set within wilc_wlan_initialize to avoid possible collisions --- drivers/staging/wilc1000/wlan.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/wilc1000/wlan.c b/drivers/staging/wilc1000/wlan.c index 1be3024eeb10f6..5f007d9c04dd2f 100644 --- a/drivers/staging/wilc1000/wlan.c +++ b/drivers/staging/wilc1000/wlan.c @@ -1550,10 +1550,6 @@ int wilc_wlan_start(struct wilc *wilc) ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); - if (!ret) - wilc->initialized = 1; - else - wilc->initialized = 0; release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP, DEV_WIFI); return (ret < 0) ? ret : 0; From 059a594c1a37e30eda5b4ca9baff9d0fd4fcd163 Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Tue, 16 Jan 2024 12:26:06 +0100 Subject: [PATCH 23/24] missing initialized flag reset --- drivers/staging/wilc1000/netdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/staging/wilc1000/netdev.c index 6963a1b70e9880..e27be97224eb5d 100644 --- a/drivers/staging/wilc1000/netdev.c +++ b/drivers/staging/wilc1000/netdev.c @@ -911,6 +911,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) fail_wilc_wlan: wilc_wlan_cleanup(dev); PRINT_ER(dev, "WLAN initialization FAILED\n"); + wl->initialized = false; } else { PRINT_WRN(vif->ndev, INIT_DBG, "wilc already initialized\n"); } From 8a8e1bf4c5766d15b4bf307c59cd3561cad7cc2f Mon Sep 17 00:00:00 2001 From: Federico Francescon Date: Tue, 16 Jan 2024 12:28:41 +0100 Subject: [PATCH 24/24] made some error message clearer --- drivers/staging/wilc1000/bt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/bt.c b/drivers/staging/wilc1000/bt.c index 48a530250151fa..705ea17cb6626e 100644 --- a/drivers/staging/wilc1000/bt.c +++ b/drivers/staging/wilc1000/bt.c @@ -307,7 +307,7 @@ int wilc_bt_power_down(struct wilc *wilc, int source) mutex_lock(&wilc->cs); - pr_info("source: %s, current bus status Wifi: %d, BT: %d\n", + pr_info("POWERING DOWN: source: %s, current bus status Wifi: %d, BT: %d\n", (source == DEV_WIFI ? "Wifi" : "BT"), wilc->power.status[DEV_WIFI], wilc->power.status[DEV_BT]); @@ -327,6 +327,7 @@ int wilc_bt_power_down(struct wilc *wilc, int source) release_bus(wilc, WILC_BUS_RELEASE_ONLY, source); if (ret) { mutex_unlock(&wilc->cs); + pr_err("deinit failed ret: 0x%0x\n", ret); return ret; } } @@ -346,7 +347,7 @@ int wilc_bt_power_up(struct wilc *wilc, int source) mutex_lock(&wilc->cs); - pr_debug("source: %s, current bus status Wifi: %d, BT: %d\n", + pr_info("POWERING UP: source: %s, current bus status Wifi: %d, BT: %d\n", (source == DEV_WIFI ? "Wifi" : "BT"), wilc->power.status[DEV_WIFI], wilc->power.status[DEV_BT]);