]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: wilc1000: Fill in missing error handling
authorMarek Vasut <marex@denx.de>
Fri, 4 Oct 2024 11:44:13 +0000 (13:44 +0200)
committerKalle Valo <kvalo@kernel.org>
Thu, 17 Oct 2024 16:47:42 +0000 (19:47 +0300)
Add error handling to chip_wakeup() and propagate the errors throughout
the entire driver. Add error handling to acquire_bus()/release_bus() and
host_sleep_notify()/host_wakeup_notify() functions as a result as well.
Fill the error handling to all call sites.

Reviewed-by: Alexis Lothoré <alexis.lothore@bootlin.com>
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://patch.msgid.link/20241004114551.40236-4-marex@denx.de
drivers/net/wireless/microchip/wilc1000/sdio.c
drivers/net/wireless/microchip/wilc1000/wlan.c
drivers/net/wireless/microchip/wilc1000/wlan.h

index 7bc6d788f33a7d1f4946831d12d62ecae9fba208..9173f6f3beabf07d8079af9486f631c641078175 100644 (file)
@@ -960,6 +960,7 @@ static int wilc_sdio_suspend(struct device *dev)
 {
        struct sdio_func *func = dev_to_sdio_func(dev);
        struct wilc *wilc = sdio_get_drvdata(func);
+       int ret;
 
        dev_info(dev, "sdio suspend\n");
 
@@ -969,7 +970,11 @@ static int wilc_sdio_suspend(struct device *dev)
        if (!IS_ERR(wilc->rtc_clk))
                clk_disable_unprepare(wilc->rtc_clk);
 
-       host_sleep_notify(wilc);
+       ret = host_sleep_notify(wilc);
+       if (ret) {
+               clk_prepare_enable(wilc->rtc_clk);
+               return ret;
+       }
 
        wilc_sdio_disable_interrupt(wilc);
 
@@ -992,9 +997,7 @@ static int wilc_sdio_resume(struct device *dev)
        wilc_sdio_init(wilc, true);
        wilc_sdio_enable_interrupt(wilc);
 
-       host_wakeup_notify(wilc);
-
-       return 0;
+       return host_wakeup_notify(wilc);
 }
 
 static const struct of_device_id wilc_of_match[] = {
index 875f0bb8af6737b349198c693a0cd5252f6f21a1..521caa498035ea3e7513a30fc2f43e9ce52bb598 100644 (file)
@@ -601,7 +601,7 @@ static int chip_allow_sleep(struct wilc *wilc)
        return 0;
 }
 
-static void chip_wakeup(struct wilc *wilc)
+static int chip_wakeup(struct wilc *wilc)
 {
        u32 ret = 0;
        u32 clk_status_val = 0, trials = 0;
@@ -630,20 +630,20 @@ static void chip_wakeup(struct wilc *wilc)
        ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg,
                                      from_host_to_fw_bit);
        if (ret)
-               return;
+               return ret;
 
        /* Set wake-up bit */
        ret = hif_func->hif_write_reg(wilc, wakeup_reg,
                                      wakeup_bit);
        if (ret)
-               return;
+               return ret;
 
        while (trials < WAKE_UP_TRIAL_RETRY) {
                ret = hif_func->hif_read_reg(wilc, clk_status_reg,
                                             &clk_status_val);
                if (ret) {
                        pr_err("Bus error %d %x\n", ret, clk_status_val);
-                       return;
+                       return ret;
                }
                if (clk_status_val & clk_status_bit)
                        break;
@@ -652,42 +652,63 @@ static void chip_wakeup(struct wilc *wilc)
        }
        if (trials >= WAKE_UP_TRIAL_RETRY) {
                pr_err("Failed to wake-up the chip\n");
-               return;
+               return -ETIMEDOUT;
        }
        /* Sometimes spi fail to read clock regs after reading
         * writing clockless registers
         */
        if (wilc->io_type == WILC_HIF_SPI)
                wilc->hif_func->hif_reset(wilc);
+
+       return 0;
 }
 
-static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
+static inline int acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
 {
+       int ret = 0;
+
        mutex_lock(&wilc->hif_cs);
-       if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP && wilc->power_save_mode)
-               chip_wakeup(wilc);
+       if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP && wilc->power_save_mode) {
+               ret = chip_wakeup(wilc);
+               if (ret)
+                       mutex_unlock(&wilc->hif_cs);
+       }
+
+       return ret;
 }
 
-static inline void release_bus(struct wilc *wilc, enum bus_release release)
+static inline int release_bus(struct wilc *wilc, enum bus_release release)
 {
+       int ret = 0;
+
        if (release == WILC_BUS_RELEASE_ALLOW_SLEEP && wilc->power_save_mode)
-               chip_allow_sleep(wilc);
+               ret = chip_allow_sleep(wilc);
        mutex_unlock(&wilc->hif_cs);
+
+       return ret;
 }
 
-void host_wakeup_notify(struct wilc *wilc)
+int host_wakeup_notify(struct wilc *wilc)
 {
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       int ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+
+       if (ret)
+               return ret;
+
        wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1);
-       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
 }
 EXPORT_SYMBOL_GPL(host_wakeup_notify);
 
-void host_sleep_notify(struct wilc *wilc)
+int host_sleep_notify(struct wilc *wilc)
 {
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       int ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+
+       if (ret)
+               return ret;
+
        wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1);
-       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
 }
 EXPORT_SYMBOL_GPL(host_sleep_notify);
 
@@ -714,6 +735,7 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
        int srcu_idx;
        u8 *txb = wilc->tx_buffer;
        struct wilc_vif *vif;
+       int rv;
 
        if (wilc->quit)
                goto out_update_cnt;
@@ -784,7 +806,10 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
                goto out_unlock;
        vmm_table[i] = 0x0;
 
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       if (ret)
+               goto out_unlock;
+
        counter = 0;
        func = wilc->hif_func;
        do {
@@ -859,7 +884,9 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
                goto out_release_bus;
        }
 
-       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       ret = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       if (ret)
+               goto out_unlock;
 
        offset = 0;
        i = 0;
@@ -921,7 +948,9 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
        for (i = 0; i < NQUEUES; i++)
                wilc->txq[i].fw.count += ac_pkt_num_to_chip[i];
 
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       if (ret)
+               goto out_unlock;
 
        ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
        if (ret)
@@ -930,7 +959,9 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
        ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
 
 out_release_bus:
-       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       if (!ret && rv)
+               ret = rv;
 
 out_unlock:
        mutex_unlock(&wilc->txq_add_to_head_cs);
@@ -1059,8 +1090,14 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
 void wilc_handle_isr(struct wilc *wilc)
 {
        u32 int_status;
+       int ret;
+
+       ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       if (ret) {
+               dev_err_ratelimited(wilc->dev, "Cannot acquire bus\n");
+               return;
+       }
 
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
        wilc->hif_func->hif_read_int(wilc, &int_status);
 
        if (int_status & DATA_INT_EXT)
@@ -1069,7 +1106,9 @@ void wilc_handle_isr(struct wilc *wilc)
        if (!(int_status & (ALL_INT_EXT)))
                wilc_unknown_isr_ext(wilc);
 
-       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       ret = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       if (ret)
+               dev_err_ratelimited(wilc->dev, "Cannot release bus\n");
 }
 EXPORT_SYMBOL_GPL(wilc_handle_isr);
 
@@ -1081,6 +1120,7 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
        u8 *dma_buffer;
        int ret = 0;
        u32 reg = 0;
+       int rv;
 
        blksz = BIT(12);
 
@@ -1091,7 +1131,9 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
        offset = 0;
        pr_debug("%s: Downloading firmware size = %d\n", __func__, buffer_size);
 
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       if (ret)
+               return ret;
 
        wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
        reg &= ~BIT(10);
@@ -1100,11 +1142,17 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
        if (reg & BIT(10))
                pr_err("%s: Failed to reset\n", __func__);
 
-       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+       ret = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+       if (ret)
+               goto fail;
+
        do {
                addr = get_unaligned_le32(&buffer[offset]);
                size = get_unaligned_le32(&buffer[offset + 4]);
-               acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+               ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+               if (ret)
+                       goto fail;
+
                offset += 8;
                while (((int)size) && (offset < buffer_size)) {
                        if (size <= blksz)
@@ -1122,7 +1170,9 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
                        offset += size2;
                        size -= size2;
                }
-               release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+               rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+               if (!ret && rv)
+                       ret = rv;
 
                if (ret) {
                        pr_err("%s Bus error\n", __func__);
@@ -1141,7 +1191,7 @@ fail:
 int wilc_wlan_start(struct wilc *wilc)
 {
        u32 reg = 0;
-       int ret;
+       int ret, rv;
        u32 chipid;
 
        if (wilc->io_type == WILC_HIF_SDIO) {
@@ -1150,7 +1200,10 @@ int wilc_wlan_start(struct wilc *wilc)
        } else if (wilc->io_type == WILC_HIF_SPI) {
                reg = 1;
        }
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+       ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+       if (ret)
+               return ret;
+
        ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
        if (ret)
                goto release;
@@ -1181,16 +1234,18 @@ int wilc_wlan_start(struct wilc *wilc)
        wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
 
 release:
-       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
-       return ret;
+       rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+       return ret ? ret : rv;
 }
 
 int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
 {
        u32 reg = 0;
-       int ret;
+       int ret, rv;
 
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       if (ret)
+               return ret;
 
        ret = wilc->hif_func->hif_read_reg(wilc, GLOBAL_MODE_CONTROL, &reg);
        if (ret)
@@ -1226,9 +1281,9 @@ int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
        ret = 0;
 release:
        /* host comm is disabled - we can't issue sleep command anymore: */
-       release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+       rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
 
-       return ret;
+       return ret ? ret : rv;
 }
 
 void wilc_wlan_cleanup(struct net_device *dev)
@@ -1434,11 +1489,13 @@ EXPORT_SYMBOL_GPL(wilc_get_chipid);
 static int init_chip(struct net_device *dev)
 {
        u32 reg;
-       int ret = 0;
+       int ret, rv;
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wilc = vif->wilc;
 
-       acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       if (ret)
+               return ret;
 
        ret = wilc_get_chipid(wilc);
        if (ret)
@@ -1470,17 +1527,19 @@ static int init_chip(struct net_device *dev)
        }
 
 release:
-       release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
 
-       return ret;
+       return ret ? ret : rv;
 }
 
 int wilc_load_mac_from_nv(struct wilc *wl)
 {
-       int ret = -EINVAL;
+       int ret, rv;
        unsigned int i;
 
-       acquire_bus(wl, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       ret = acquire_bus(wl, WILC_BUS_ACQUIRE_AND_WAKEUP);
+       if (ret)
+               return ret;
 
        for (i = 0; i < WILC_NVMEM_MAX_NUM_BANK; i++) {
                int bank_offset = get_bank_offset_from_bank_index(i);
@@ -1519,14 +1578,14 @@ int wilc_load_mac_from_nv(struct wilc *wl)
                break;
        }
 
-       release_bus(wl, WILC_BUS_RELEASE_ALLOW_SLEEP);
-       return ret;
+       rv = release_bus(wl, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       return ret ? ret : rv;
 }
 EXPORT_SYMBOL_GPL(wilc_load_mac_from_nv);
 
 int wilc_wlan_init(struct net_device *dev)
 {
-       int ret = 0;
+       int ret = 0, rv;
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wilc;
 
@@ -1535,11 +1594,16 @@ int wilc_wlan_init(struct net_device *dev)
        wilc->quit = 0;
 
        if (!wilc->hif_func->hif_is_init(wilc)) {
-               acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+               ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
+               if (ret)
+                       return ret;
+
                ret = wilc->hif_func->hif_init(wilc, false);
                if (!ret)
                        ret = wilc_get_chipid(wilc);
-               release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+               rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
+               if (!ret && rv)
+                       ret = rv;
                if (ret)
                        goto fail;
 
index 90ba76cf14dd18f30f5278b5ac6fa784ac085d14..552590823e44423eff9a3ed111952e1fcf8fe1ce 100644 (file)
@@ -436,8 +436,8 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev);
 
 void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size);
 bool wilc_wfi_mgmt_frame_rx(struct wilc_vif *vif, u8 *buff, u32 size);
-void host_wakeup_notify(struct wilc *wilc);
-void host_sleep_notify(struct wilc *wilc);
+int host_wakeup_notify(struct wilc *wilc);
+int host_sleep_notify(struct wilc *wilc);
 int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
                         u32 count);
 int wilc_wlan_init(struct net_device *dev);