Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -813,7 +813,7 @@ 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,
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);
@@ -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,7 +1145,7 @@ 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,
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);

+4 −4
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ 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,
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,
@@ -272,7 +272,7 @@ 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,
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);
+8 −3
Original line number Diff line number Diff line
@@ -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,
	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");