From 69c6ac60f559f85ed47fbfc2bcaa43a7bc1583ff Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 26 Sep 2012 07:54:43 +0530 Subject: [PATCH] ath9k: Handle errors properly in MCI initialization The MCI initialization path has various points of failures, handle these to ensure that we bail out correctly in such cases. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mci.c | 21 +++++++++++---------- drivers/net/wireless/ath/ath9k/ar9003_mci.h | 8 ++++---- drivers/net/wireless/ath/ath9k/mci.c | 11 ++++++++--- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 8dbb60b53f1a..44c202ce6c66 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -813,8 +813,8 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable) AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); } -void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, - bool is_full_sleep) +int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, + bool is_full_sleep) { struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; @@ -824,14 +824,13 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, is_full_sleep, is_2g); if (!mci->gpm_addr && !mci->sched_addr) { - ath_dbg(common, MCI, - "MCI GPM and schedule buffers are not allocated\n"); - return; + ath_err(common, "MCI GPM and schedule buffers are not allocated\n"); + return -ENOMEM; } if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { - ath_dbg(common, MCI, "BTCOEX control register is dead\n"); - return; + ath_err(common, "BTCOEX control register is dead\n"); + return -EINVAL; } /* Program MCI DMA related registers */ @@ -913,6 +912,8 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, if (en_int) ar9003_mci_enable_interrupt(ah); + + return 0; } void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) @@ -1144,8 +1145,8 @@ void ar9003_mci_init_cal_done(struct ath_hw *ah) ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); } -void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, - u16 len, u32 sched_addr) +int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, + u16 len, u32 sched_addr) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; @@ -1154,7 +1155,7 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, mci->gpm_len = len; mci->sched_addr = sched_addr; - ar9003_mci_reset(ah, true, true, true); + return ar9003_mci_reset(ah, true, true, true); } EXPORT_SYMBOL(ar9003_mci_setup); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 30acf2869aa4..2a2d01889613 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -249,8 +249,8 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, u32 *payload, u8 len, bool wait_done, bool check_bt); u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type); -void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, - u16 len, u32 sched_addr); +int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, + u16 len, u32 sched_addr); void ar9003_mci_cleanup(struct ath_hw *ah); void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, u32 *rx_msg_intr); @@ -272,8 +272,8 @@ void ar9003_mci_check_bt(struct ath_hw *ah); bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan); int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, struct ath9k_hw_cal_data *caldata); -void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, - bool is_full_sleep); +int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, + bool is_full_sleep); void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); void ar9003_mci_set_power_awake(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 8f51e9e358fd..ec2d7c807567 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -392,6 +392,7 @@ int ath_mci_setup(struct ath_softc *sc) struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_mci_coex *mci = &sc->mci_coex; struct ath_mci_buf *buf = &mci->sched_buf; + int ret; buf->bf_addr = dma_alloc_coherent(sc->dev, ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, @@ -411,9 +412,13 @@ int ath_mci_setup(struct ath_softc *sc) mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + mci->sched_buf.bf_len; mci->gpm_buf.bf_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len; - ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr, - mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), - mci->sched_buf.bf_paddr); + ret = ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr, + mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), + mci->sched_buf.bf_paddr); + if (ret) { + ath_err(common, "Failed to initialize MCI\n"); + return ret; + } INIT_WORK(&sc->mci_work, ath9k_mci_work); ath_dbg(common, MCI, "MCI Initialized\n"); -- 2.20.1