Commit 1241c565 authored by Marek Vasut's avatar Marek Vasut Committed by Kalle Valo
Browse files

wifi: wilc1000: Fill in missing error handling



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: default avatarAlexis Lothoré <alexis.lothore@bootlin.com>
Signed-off-by: default avatarMarek Vasut <marex@denx.de>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://patch.msgid.link/20241004114551.40236-4-marex@denx.de
parent 0a6ea2e2
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -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[] = {
+109 −45
Original line number Diff line number Diff line
@@ -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);
	}

static inline void release_bus(struct wilc *wilc, enum bus_release release)
	return ret;
}

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 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
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;

+2 −2
Original line number Diff line number Diff line
@@ -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);