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: Ido Yariv <ido@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
committed by
Luciano Coelho
parent
0c2a6ce04e
commit
8b7c0fc356
@@ -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);
|
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)
|
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)
|
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)
|
static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
|
||||||
|
@@ -378,9 +378,9 @@ 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_1 *status_1,
|
||||||
struct wl_fw_status_2 *status_2)
|
struct wl_fw_status_2 *status_2)
|
||||||
{
|
{
|
||||||
struct wl12xx_vif *wlvif;
|
struct wl12xx_vif *wlvif;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
@@ -388,12 +388,15 @@ static void wl12xx_fw_status(struct wl1271 *wl,
|
|||||||
int avail, freed_blocks;
|
int avail, freed_blocks;
|
||||||
int i;
|
int i;
|
||||||
size_t status_len;
|
size_t status_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
|
status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
|
||||||
sizeof(*status_2) + wl->fw_status_priv_len;
|
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);
|
status_len, false);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
|
wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
|
||||||
"drv_rx_counter = %d, tx_results_counter = %d)",
|
"drv_rx_counter = %d, tx_results_counter = %d)",
|
||||||
@@ -462,6 +465,8 @@ static void wl12xx_fw_status(struct wl1271 *wl,
|
|||||||
getnstimeofday(&ts);
|
getnstimeofday(&ts);
|
||||||
wl->time_offset = (timespec_to_ns(&ts) >> 10) -
|
wl->time_offset = (timespec_to_ns(&ts) >> 10) -
|
||||||
(s64)le32_to_cpu(status_2->fw_localtime);
|
(s64)le32_to_cpu(status_2->fw_localtime);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wl1271_flush_deferred_work(struct wl1271 *wl)
|
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);
|
clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
|
||||||
smp_mb__after_clear_bit();
|
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);
|
wlcore_hw_tx_immediate_compl(wl);
|
||||||
|
|
||||||
@@ -781,6 +790,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|||||||
u32 offset;
|
u32 offset;
|
||||||
u32 end_of_log;
|
u32 end_of_log;
|
||||||
u8 *block;
|
u8 *block;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
|
if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
|
||||||
(wl->conf.fwlog.mem_blocks == 0))
|
(wl->conf.fwlog.mem_blocks == 0))
|
||||||
@@ -802,7 +812,10 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|||||||
wl12xx_cmd_stop_fwlog(wl);
|
wl12xx_cmd_stop_fwlog(wl);
|
||||||
|
|
||||||
/* Read the first memory block address */
|
/* 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);
|
addr = le32_to_cpu(wl->fw_status_2->log_start_addr);
|
||||||
if (!addr)
|
if (!addr)
|
||||||
goto out;
|
goto out;
|
||||||
|
Reference in New Issue
Block a user