mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-07 20:58:14 -04:00
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: Alexis Lothoré <alexis.lothore@bootlin.com> Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://patch.msgid.link/20241004114551.40236-4-marex@denx.de
This commit is contained in:
@@ -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[] = {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void release_bus(struct wilc *wilc, enum bus_release release)
|
||||
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 &= ~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, ®);
|
||||
|
||||
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, ®);
|
||||
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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user