Commit 69c6ac60 authored by Sujith Manoharan's avatar Sujith Manoharan Committed by John W. Linville

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: default avatarSujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent a549459c
...@@ -813,8 +813,8 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable) ...@@ -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); AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);
} }
void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep) bool is_full_sleep)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; 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, ...@@ -824,14 +824,13 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
is_full_sleep, is_2g); is_full_sleep, is_2g);
if (!mci->gpm_addr && !mci->sched_addr) { if (!mci->gpm_addr && !mci->sched_addr) {
ath_dbg(common, MCI, ath_err(common, "MCI GPM and schedule buffers are not allocated\n");
"MCI GPM and schedule buffers are not allocated\n"); return -ENOMEM;
return;
} }
if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
ath_dbg(common, MCI, "BTCOEX control register is dead\n"); ath_err(common, "BTCOEX control register is dead\n");
return; return -EINVAL;
} }
/* Program MCI DMA related registers */ /* Program MCI DMA related registers */
...@@ -913,6 +912,8 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, ...@@ -913,6 +912,8 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
if (en_int) if (en_int)
ar9003_mci_enable_interrupt(ah); ar9003_mci_enable_interrupt(ah);
return 0;
} }
void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) 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) ...@@ -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); 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, int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
u16 len, u32 sched_addr) u16 len, u32 sched_addr)
{ {
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; 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, ...@@ -1154,7 +1155,7 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
mci->gpm_len = len; mci->gpm_len = len;
mci->sched_addr = sched_addr; 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); EXPORT_SYMBOL(ar9003_mci_setup);
......
...@@ -249,8 +249,8 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, ...@@ -249,8 +249,8 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
u32 *payload, u8 len, bool wait_done, u32 *payload, u8 len, bool wait_done,
bool check_bt); bool check_bt);
u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type); 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, int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
u16 len, u32 sched_addr); u16 len, u32 sched_addr);
void ar9003_mci_cleanup(struct ath_hw *ah); void ar9003_mci_cleanup(struct ath_hw *ah);
void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
u32 *rx_msg_intr); u32 *rx_msg_intr);
...@@ -272,8 +272,8 @@ void ar9003_mci_check_bt(struct ath_hw *ah); ...@@ -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); 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, int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata); struct ath9k_hw_cal_data *caldata);
void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep); bool is_full_sleep);
void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); 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_bt_gain_ctrl(struct ath_hw *ah);
void ar9003_mci_set_power_awake(struct ath_hw *ah); void ar9003_mci_set_power_awake(struct ath_hw *ah);
......
...@@ -392,6 +392,7 @@ int ath_mci_setup(struct ath_softc *sc) ...@@ -392,6 +392,7 @@ int ath_mci_setup(struct ath_softc *sc)
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_mci_coex *mci = &sc->mci_coex; struct ath_mci_coex *mci = &sc->mci_coex;
struct ath_mci_buf *buf = &mci->sched_buf; struct ath_mci_buf *buf = &mci->sched_buf;
int ret;
buf->bf_addr = dma_alloc_coherent(sc->dev, buf->bf_addr = dma_alloc_coherent(sc->dev,
ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE,
...@@ -411,9 +412,13 @@ int ath_mci_setup(struct ath_softc *sc) ...@@ -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_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; 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, ret = ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr,
mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4),
mci->sched_buf.bf_paddr); 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); INIT_WORK(&sc->mci_work, ath9k_mci_work);
ath_dbg(common, MCI, "MCI Initialized\n"); ath_dbg(common, MCI, "MCI Initialized\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment