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

Commit 8b7c0fc3 authored by Ido Yariv's avatar Ido Yariv Committed by Luciano Coelho
Browse files

wlcore: Propagate errors from wlcore_raw_*_data functions



wlcore_raw_read_data is called when the FW status is read which happens
while handling interrupts and when the FW log is read following a
recovery. Request a recovery in the former case, and don't read the FW
log in case the FW status read failed.

Signed-off-by: default avatarIdo Yariv <ido@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 0c2a6ce0
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -65,16 +65,16 @@ static inline int wlcore_raw_read(struct wl1271 *wl, int addr, void *buf,
	return wl->if_ops->read(wl->dev, addr, buf, len, fixed);
}

static inline void wlcore_raw_read_data(struct wl1271 *wl, int reg, void *buf,
static inline int wlcore_raw_read_data(struct wl1271 *wl, int reg, void *buf,
				       size_t len, bool fixed)
{
	wlcore_raw_read(wl, wl->rtable[reg], buf, len, fixed);
	return wlcore_raw_read(wl, wl->rtable[reg], buf, len, fixed);
}

static inline void wlcore_raw_write_data(struct wl1271 *wl, int reg, void *buf,
static inline int wlcore_raw_write_data(struct wl1271 *wl, int reg, void *buf,
					size_t len, bool fixed)
{
	wlcore_raw_write(wl, wl->rtable[reg], buf, len, fixed);
	return wlcore_raw_write(wl, wl->rtable[reg], buf, len, fixed);
}

static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
+20 −7
Original line number Diff line number Diff line
@@ -378,7 +378,7 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
	}
}

static void wl12xx_fw_status(struct wl1271 *wl,
static int wlcore_fw_status(struct wl1271 *wl,
			    struct wl_fw_status_1 *status_1,
			    struct wl_fw_status_2 *status_2)
{
@@ -388,12 +388,15 @@ static void wl12xx_fw_status(struct wl1271 *wl,
	int avail, freed_blocks;
	int i;
	size_t status_len;
	int ret;

	status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
		sizeof(*status_2) + wl->fw_status_priv_len;

	wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1,
	ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1,
				   status_len, false);
	if (ret < 0)
		return ret;

	wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
		     "drv_rx_counter = %d, tx_results_counter = %d)",
@@ -462,6 +465,8 @@ static void wl12xx_fw_status(struct wl1271 *wl,
	getnstimeofday(&ts);
	wl->time_offset = (timespec_to_ns(&ts) >> 10) -
		(s64)le32_to_cpu(status_2->fw_localtime);

	return 0;
}

static void wl1271_flush_deferred_work(struct wl1271 *wl)
@@ -530,7 +535,11 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
		clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
		smp_mb__after_clear_bit();

		wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
		ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
		if (ret < 0) {
			wl12xx_queue_recovery_work(wl);
			goto out;
		}

		wlcore_hw_tx_immediate_compl(wl);

@@ -781,6 +790,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
	u32 offset;
	u32 end_of_log;
	u8 *block;
	int ret;

	if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
	    (wl->conf.fwlog.mem_blocks == 0))
@@ -802,7 +812,10 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
		wl12xx_cmd_stop_fwlog(wl);

	/* Read the first memory block address */
	wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
	ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
	if (ret < 0)
		goto out;

	addr = le32_to_cpu(wl->fw_status_2->log_start_addr);
	if (!addr)
		goto out;