From bc1a720197add99d877e4099a4ad272aec88b74f Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 21 Aug 2010 20:36:04 +0200 Subject: [PATCH] carl9170 firmware: mac reset refactoring, take-2 No matter what, the current MAC-only reset code is not adequate, if the MAC state machine gets completely stuck. This patch introduces a configurable switch, which allows the firmware to delegate a full-chip reset to the driver. Signed-off-by: Christian Lamparter --- carlfw/Kconfig | 5 +++++ carlfw/src/cmd.c | 3 +++ carlfw/src/wlan.c | 21 +++++++++++++-------- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/carlfw/Kconfig b/carlfw/Kconfig index bacb6f2..9326704 100644 --- a/carlfw/Kconfig +++ b/carlfw/Kconfig @@ -158,6 +158,11 @@ config CARL9170FW_VIFS_NUM prompt "Number of additional pseudo virtual interfaces" depends on CARL9170FW_EXPERIMENTAL +config CARL9170FW_FW_MAC_RESET + def_bool n + prompt "Firmware MAC Chip recovery" + depends on CARL9170FW_EXPERIMENTAL + config CARL9170FW_BROKEN_FEATURES def_bool n prompt "Broken Featurs" diff --git a/carlfw/src/cmd.c b/carlfw/src/cmd.c index 112bf87..281ae9c 100644 --- a/carlfw/src/cmd.c +++ b/carlfw/src/cmd.c @@ -59,12 +59,14 @@ void handle_cmd(struct carl9170_rsp *resp) break; case CARL9170_CMD_SWRST: +#ifdef CONFIG_CARL9170FW_FW_MAC_RESET /* * Command has no payload, so the response * has no payload either. * resp->hdr.len = 0; */ fw.wlan.mac_reset = CARL9170_MAC_RESET_FORCE; +#endif /* CONFIG_CARL9170FW_FW_MAC_RESET */ break; case CARL9170_CMD_REBOOT: @@ -129,6 +131,7 @@ void handle_cmd(struct carl9170_rsp *resp) #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIOS */ default: + BUG("Unknown command %x\n", cmd->hdr.cmd); break; } } diff --git a/carlfw/src/wlan.c b/carlfw/src/wlan.c index 367dfab..cd169ff 100644 --- a/carlfw/src/wlan.c +++ b/carlfw/src/wlan.c @@ -265,6 +265,9 @@ static bool wlan_tx_status(struct dma_queue *queue, success = true; + /* update hangcheck */ + fw.wlan.last_tx_desc_num[qidx] = 0; + if (!!(desc->ctrl & AR9170_CTRL_FAIL)) { txfail = !!(desc->ctrl & AR9170_CTRL_TXFAIL); @@ -342,9 +345,6 @@ static bool wlan_tx_status(struct dma_queue *queue, unhide_super(desc); - /* update hangcheck */ - fw.wlan.last_tx_desc_num[qidx] = 0; - #ifdef CONFIG_CARL9170FW_HANDLE_BACK_REQ if (unlikely(super == (void *) &dma_mem.reserved.ba)) { fw.wlan.ba_desc = desc; @@ -562,14 +562,11 @@ static void wlan_check_rx_overrun(void) fw.wlan.rx_overruns += overruns = get(AR9170_MAC_REG_RX_OVERRUN); if (unlikely(overruns)) { if (overruns == total) { - /* - * Theoretically, it should be enough to - * trigger the WLAN RX DMA bit. But the - * original firmware wanted a reset... - */ DBG("RX Overrun"); fw.wlan.mac_reset++; } + + wlan_trigger(AR9170_DMA_TRIGGER_RXQ); } } @@ -895,6 +892,7 @@ static void wlan_check_hang(void) } } +#ifdef CONFIG_CARL9170FW_FW_MAC_RESET /* * NB: Resetting the MAC is a two-edged sword. * On most occasions, it does what it is supposed to do. @@ -997,6 +995,13 @@ static void wlan_mac_reset(void) set(AR9170_MAC_REG_DMA_RXQ_ADDR, (uint32_t) fw.wlan.rx_queue.head); wlan_trigger(AR9170_DMA_TRIGGER_RXQ); } +#else +static void wlan_mac_reset(void) +{ + /* The driver takes care of reinitializing the device */ + BUG("MAC RESET"); +} +#endif /* CONFIG_CARL9170FW_FW_MAC_RESET */ void __cold wlan_timer(void) { -- 2.31.1