carl9170 firmware: cleanup dma memory before reset
[carl9170fw.git] / carlfw / usb / main.c
index f32efc2a9a0f15aaea30a1b858d21336c3c18701..6545ec0931180e709936c264afb8394d4ed52a14 100644 (file)
@@ -27,7 +27,6 @@
 #include "printf.h"
 #include "timer.h"
 #include "rom.h"
-#include "gpio.h"
 #include "shared/phy.h"
 
 #ifdef CONFIG_CARL9170FW_DEBUG_USB
@@ -65,7 +64,14 @@ static struct carl9170_rsp *get_int_buf(void)
 {
        struct carl9170_rsp *tmp;
 
-       tmp = &fw.usb.int_buf[fw.usb.int_tail_index++];
+       /* fetch the _oldest_ buffer from the ring */
+       tmp = &fw.usb.int_buf[fw.usb.int_tail_index];
+
+       /* assign a unique sequence for every response/trap */
+       tmp->hdr.seq = fw.usb.int_tail_index;
+
+       fw.usb.int_tail_index++;
+
        fw.usb.int_tail_index %= CARL9170_INT_RQ_CACHES;
        if (fw.usb.int_pending != CARL9170_INT_RQ_CACHES)
                fw.usb.int_pending++;
@@ -152,6 +158,7 @@ static void usb_status_in(void)
                goto reclaim;
        }
 
+       fw.usb.int_desc->ctrl = AR9170_CTRL_FS_BIT | AR9170_CTRL_LS_BIT;
        fw.usb.int_desc->totalLen = tlen;
        fw.usb.int_desc->dataSize = tlen;
 
@@ -202,26 +209,6 @@ void send_cmd_to_host(const uint8_t len, const uint8_t type,
        usb_trigger_in();
 }
 
-/* Reset all the USB FIFO used for WLAN */
-static void usb_reset_FIFO(void)
-{
-       uint32_t val;
-
-       /*
-        * of course,
-        * simpley ORing AR9170_MAC_POWER_STATE_CTRL_RESET
-        * would be... I dunno, maybe: just to simple?
-        */
-
-       val = get(AR9170_MAC_REG_POWER_STATE_CTRL);
-       val |= AR9170_MAC_POWER_STATE_CTRL_RESET;
-       set(AR9170_MAC_REG_POWER_STATE_CTRL, val);
-
-       /* Reset USB FIFO */
-       set(AR9170_PWR_REG_ADDA_BB, AR9170_PWR_ADDA_BB_USB_FIFO_RESET);
-       set(AR9170_PWR_REG_ADDA_BB, 0x0);
-}
-
 /* Turn off ADDA/RF power, PLL */
 static void turn_power_off(void)
 {
@@ -229,11 +216,22 @@ static void turn_power_off(void)
        set(AR9170_PHY_REG_ADC_CTL, 0xa0000000 |
            AR9170_PHY_ADC_CTL_OFF_PWDADC | AR9170_PHY_ADC_CTL_OFF_PWDDAC);
 
+       /* This will also turn-off the LEDs */
        set(AR9170_GPIO_REG_PORT_DATA, 0);
        set(AR9170_GPIO_REG_PORT_TYPE, 0xf);
 
        set(AR9170_PWR_REG_BASE, 0x40021);
-       set(AR9170_PWR_REG_ADDA_BB, 0);
+
+       set(AR9170_MAC_REG_DMA_TRIGGER, 0);
+
+       set(AR9170_MAC_REG_POWER_STATE_CTRL,
+           AR9170_MAC_POWER_STATE_CTRL_RESET);
+
+       /* Reset USB FIFO */
+       set(AR9170_PWR_REG_RESET, AR9170_PWR_RESET_COMMIT_RESET_MASK |
+                                 AR9170_PWR_RESET_DMA_MASK |
+                                 AR9170_PWR_RESET_WLAN_MASK);
+       set(AR9170_PWR_REG_RESET, 0x0);
 
        clock_set(false, AHB_20_22MHZ);
 
@@ -272,24 +270,23 @@ static void turn_power_off(void)
        set(AR9170_PHY_REG_ADC_SERIAL_CTL, AR9170_PHY_ADC_SCTL_SEL_INTERNAL_ADDAC);
 }
 
-void __attribute__((noreturn)) reboot(void)
+void __noreturn reboot(void)
 {
-       /* turn off leds */
-       led_set(0);
+       set(AR9170_MAC_REG_DMA_TRIGGER, 0);
 
        /* write watchdog magic pattern for suspend  */
        andl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0xffff);
        orl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0x98760000);
 
        /* Disable watchdog */
-       orl(AR9170_TIMER_REG_WATCH_DOG, 0xffff);
-
-       /* Reset USB FIFO */
-       usb_reset_FIFO();
+       set(AR9170_TIMER_REG_WATCH_DOG, 0xffff);
 
        /* Turn off power */
        turn_power_off();
 
+       /* clean bootloader workspace */
+       memset(&dma_mem, 0, sizeof(dma_mem));
+
        /* add by ygwei for work around USB PHY chirp sequence problem */
        set(0x10f100, 0x12345678);
 
@@ -394,25 +391,3 @@ void handle_usb(void)
                usb_trigger_in();
 }
 
-#ifdef CONFIG_CARL9170FW_USB_WATCHDOG
-void usb_watchdog_timer(void)
-{
-       if (fw.usb.watchdog.state == cpu_to_le32(CARL9170_USB_WATCHDOG_INACTIVE))
-               return;
-
-       fw.usb.watchdog.state++;
-
-       if (le32_to_cpu(fw.usb.watchdog.state) >= CARL9170_USB_WATCHDOG_TRIGGER_THRESHOLD) {
-               for (;;) {
-                       /*
-                        * Simply wait until the HW watchdog
-                        * timer has elapsed.
-                        */
-               }
-       }
-
-       send_cmd_to_host(sizeof(fw.usb.watchdog), CARL9170_RSP_USB_WD,
-                        0x80, (uint8_t *) &fw.usb.watchdog);
-}
-#endif /* CONFIG_CARL9170FW_USB_WATCHDOG */
-