ath10k: fix missing checks for bmi reads and writes
authorKangjie Lu <kjlu@umn.edu>
Fri, 15 Mar 2019 05:19:03 +0000 (00:19 -0500)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 23 Sep 2019 08:16:23 +0000 (11:16 +0300)
ath10k_bmi_write32 and ath10k_bmi_read32 can fail. The fix
checks their statuses to avoid potential undefined behaviors.

Signed-off-by: Kangjie Lu <kjlu@umn.edu>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/ath10k/core.c

index 383d4fa555a889f16b642171b23301c1f3651132..3d91a4025cfc8541cd70e5df9a16ba59b4f3dfb4 100644 (file)
@@ -677,13 +677,22 @@ static void ath10k_send_suspend_complete(struct ath10k *ar)
        complete(&ar->target_suspend);
 }
 
-static void ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode)
+static int ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode)
 {
+       int ret;
        u32 param = 0;
 
-       ath10k_bmi_write32(ar, hi_mbox_io_block_sz, 256);
-       ath10k_bmi_write32(ar, hi_mbox_isr_yield_limit, 99);
-       ath10k_bmi_read32(ar, hi_acs_flags, &param);
+       ret = ath10k_bmi_write32(ar, hi_mbox_io_block_sz, 256);
+       if (ret)
+               return ret;
+
+       ret = ath10k_bmi_write32(ar, hi_mbox_isr_yield_limit, 99);
+       if (ret)
+               return ret;
+
+       ret = ath10k_bmi_read32(ar, hi_acs_flags, &param);
+       if (ret)
+               return ret;
 
        /* Data transfer is not initiated, when reduced Tx completion
         * is used for SDIO. disable it until fixed
@@ -700,14 +709,23 @@ static void ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode)
        else
                param |= HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET;
 
-       ath10k_bmi_write32(ar, hi_acs_flags, param);
+       ret = ath10k_bmi_write32(ar, hi_acs_flags, param);
+       if (ret)
+               return ret;
 
        /* Explicitly set fwlog prints to zero as target may turn it on
         * based on scratch registers.
         */
-       ath10k_bmi_read32(ar, hi_option_flag, &param);
+       ret = ath10k_bmi_read32(ar, hi_option_flag, &param);
+       if (ret)
+               return ret;
+
        param |= HI_OPTION_DISABLE_DBGLOG;
-       ath10k_bmi_write32(ar, hi_option_flag, param);
+       ret = ath10k_bmi_write32(ar, hi_option_flag, param);
+       if (ret)
+               return ret;
+
+       return 0;
 }
 
 static int ath10k_init_configure_target(struct ath10k *ar)
@@ -2565,8 +2583,13 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
                if (status)
                        goto err;
 
-               if (ar->hif.bus == ATH10K_BUS_SDIO)
-                       ath10k_init_sdio(ar, mode);
+               if (ar->hif.bus == ATH10K_BUS_SDIO) {
+                       status = ath10k_init_sdio(ar, mode);
+                       if (status) {
+                               ath10k_err(ar, "failed to init SDIO: %d\n", status);
+                               goto err;
+                       }
+               }
        }
 
        ar->htc.htc_ops.target_send_suspend_complete =