Merge carl9170fw
authorChristian Lamparter <chunkeey@googlemail.com>
Fri, 11 Mar 2011 00:42:35 +0000 (01:42 +0100)
committerChristian Lamparter <chunkeey@googlemail.com>
Fri, 11 Mar 2011 00:42:35 +0000 (01:42 +0100)
Conflicts:
carlfw/Kconfig
carlfw/include/wl.h
carlfw/src/wlan.c

17 files changed:
carlfw/Kconfig
carlfw/include/carl9170.h
carlfw/include/dma.h
carlfw/include/wl.h
carlfw/src/cmd.c
carlfw/src/dma.c
carlfw/src/fw.c
carlfw/src/hostif.c
carlfw/src/main.c
carlfw/src/rf.c
carlfw/src/wlan.c
include/generated/defconfig [deleted file]
include/shared/fwdesc.h
include/shared/hw.h
include/shared/version.h
include/shared/wlan.h
tools/carlu/src/tx.c

index 1c5718ae60caa986ce1107e07043814dce4ced12..18d09586f583695f018972a4d827f3b688967d90 100644 (file)
@@ -31,15 +31,6 @@ config CARL9170FW_RX_FRAME_LEN
        default 16384 if CARL9170FW_RX_FRAME_LEN_16384
        default 32768 if CARL9170FW_RX_FRAME_LEN_32768
 
-config CARL9170FW_WATCHDOG
-       def_bool y
-       prompt "Activate HW Watchdog"
-       ---help---
-        The watchdog will notify the application as soon as the firmware
-        has stalled.
-
-        Say Y.
-
 config CARL9170FW_GPIO_INTERRUPT
        def_bool y
        prompt "GPIO Software Interrupt"
@@ -123,16 +114,6 @@ config CARL9170FW_EXPERIMENTAL
        def_bool y
        prompt "Experimental Features"
 
-config CARL9170FW_PSM
-       def_bool y
-       prompt "Firmware Supported Power-saving Management"
-       depends on CARL9170FW_EXPERIMENTAL && CARL9170FW_RADIO_FUNCTIONS
-       ---help---
-        This options enables a interface for the application to
-        switch off the RF/PHY (in order to save power). And the
-        Firmware will automatically turn it on again, when the
-        PRETBTT event fires.
-
 config CARL9170FW_WOL_OPTION
        def_bool n
        prompt "Wakeup on WLAN"
@@ -179,6 +160,11 @@ config CARL9170FW_FW_MAC_RESET
        prompt "Firmware MAC Chip recovery"
        depends on CARL9170FW_EXPERIMENTAL
 
+config CARL9170FW_NOISY_MAC_RESET
+       def_bool n
+       prompt "Notify MAC RESET events"
+       depends on CARL9170FW_FW_MAC_RESET
+
 config CARL9170FW_BROKEN_FEATURES
        def_bool n
        prompt "Broken Featurs"
@@ -208,7 +194,7 @@ config CARL9170FW_DEBUG_UART
 
 config CARL9170FW_WATCHDOG_BUTTON
        def_bool n
-       depends on CARL9170FW_BROKEN && CARL9170FW_WATCHDOG && CARL9170FW_GPIO_INTERRUPT
+       depends on CARL9170FW_BROKEN && CARL9170FW_GPIO_INTERRUPT
        prompt "Trigger Watchdog by pressing the WPS button"
 
 choice CARL9170FW_UART_CLOCK
index b05d8beaec22ee3a70ae31078d1d0b72310e94f7..85ea1d2425bd5895915aff9525cb407a61f01bac 100644 (file)
@@ -100,8 +100,8 @@ struct firmware_context_struct {
                struct carl9170_tx_superframe *ampdu_prev[__AR9170_NUM_TX_QUEUES];
 
                /* Hardware DMA queue unstuck/fix detection */
-               unsigned int last_tx_desc_num[__AR9170_NUM_TX_QUEUES];
-               struct dma_desc *last_tx_desc[__AR9170_NUM_TX_QUEUES];
+               unsigned int last_super_num[__AR9170_NUM_TX_QUEUES];
+               struct carl9170_tx_superframe *last_super[__AR9170_NUM_TX_QUEUES];
                unsigned int mac_reset;
                unsigned int soft_int;
 
@@ -182,9 +182,7 @@ struct firmware_context_struct {
                unsigned int frequency;
                unsigned int ht_settings;
 
-#ifdef CONFIG_CARL9170FW_PSM
                struct carl9170_psm psm;
-#endif /* CONFIG_CARL9170FW_PSM */
 #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
        } phy;
 
index 70417360854bcab334b47fc08d0d6c14f96fc508..11a760dfc98139cb68c921d188d1cc19c8b71941 100644 (file)
@@ -215,7 +215,6 @@ struct dma_desc *dma_unlink_head(struct dma_queue *queue);
 void dma_init_descriptors(void);
 void dma_reclaim(struct dma_queue *q, struct dma_desc *desc);
 void dma_put(struct dma_queue *q, struct dma_desc *desc);
-void dma_queue_reclaim(struct dma_queue *dst, struct dma_queue *src);
 
 static inline __inline bool is_terminator(struct dma_queue *q, struct dma_desc *desc)
 {
@@ -275,6 +274,10 @@ static inline __inline struct dma_desc *dma_dequeue_not_bits(struct dma_queue *q
             (desc->status & AR9170_OWN_BITS) == bits);                 \
             desc = (queue)->head)
 
+#define __for_each_desc_continue(desc, queue)                          \
+       for (;desc != (queue)->terminator;                              \
+            desc = (desc)->lastAddr->nextAddr)
+
 #define __for_each_desc(desc, queue)                                   \
        for (desc = (queue)->head;                                      \
             desc != (queue)->terminator;                               \
@@ -311,6 +314,15 @@ static inline __inline void dma_rearm(struct dma_desc *desc)
                        AR9170_OWN_BITS_HW);
 }
 
+static inline __inline void dma_fix_downqueue(struct dma_desc *desc)
+{
+       desc->status = AR9170_OWN_BITS_HW;
+       desc->ctrl = 0;
+       desc->dataSize = 0;
+       desc->totalLen = AR9170_BLOCK_SIZE;
+       desc->lastAddr = desc;
+}
+
 static inline void __check_desc(void)
 {
        struct ar9170_dma_memory mem;
index 7428d1a28760901d293c9c06f6a49a7d7ecb9db7..e1c8bbd014ab17407847c1df3902e43aaa262787 100644 (file)
@@ -52,6 +52,11 @@ static inline __inline struct dma_desc *get_wlan_txq_addr(const unsigned int q)
        return getp(AR9170_MAC_REG_DMA_TXQ_CURR_ADDR + (q << 3));
 }
 
+static inline __inline struct dma_desc *get_wlan_txq_last_addr(const unsigned int q)
+{
+       return getp(AR9170_MAC_REG_DMA_TXQ_LAST_ADDR + (q << 2));
+}
+
 static inline __inline void wlan_trigger(const uint32_t queue_bit)
 {
        set(AR9170_MAC_REG_DMA_TRIGGER, queue_bit);
@@ -210,6 +215,11 @@ static inline __inline struct carl9170_tx_superframe *get_super(struct dma_desc
                            f);
 }
 
+static inline __inline struct carl9170_tx_superframe *__get_super(struct dma_desc *desc)
+{
+       return DESC_PAYLOAD(desc);
+}
+
 static inline __inline void hide_super(struct dma_desc *desc)
 {
        desc->dataAddr = (uint8_t *)
@@ -253,6 +263,9 @@ void wlan_modify_beacon(const unsigned int vif,
                        const unsigned int bcn_addr,
                        const unsigned int bcn_len);
 
+void wlan_tx_complete(struct carl9170_tx_superframe *super,
+                      bool txs);
+
 static inline void wlan_prepare_wol(void)
 {
        /* set filter policy to: discard everything */
index fd8faf588e66c957915f2c95ef92d0df92195f24..2bbfcffaa71f1cacbdda4b33ddcee3e60eef8c72 100644 (file)
@@ -128,13 +128,11 @@ void handle_cmd(struct carl9170_rsp *resp)
                rf_notify_set_channel();
                break;
 
-# ifdef CONFIG_CARL9170FW_PSM
        case CARL9170_CMD_PSM:
                resp->hdr.len = 0;
                fw.phy.psm.state = le32_to_cpu(cmd->psm.state);
                rf_psm();
                break;
-# endif /* CONFIG_CARL9170FW_PSM */
 #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIOS */
 
        default:
index 92a8a68b082331e66a3b565de5c3608b777d38a9..de9c8b91b71489e0ff115b966a0d237005574fe6 100644 (file)
@@ -165,11 +165,13 @@ void dma_init_descriptors(void)
  */
 void dma_reclaim(struct dma_queue *q, struct dma_desc *desc)
 {
-       struct dma_desc *tmpDesc;
+       struct dma_desc *tmpDesc, *last;
        struct dma_desc tdesc;
 
        /* 1. Set OWN bit to HW for all TDs to be added, clear ctrl and size */
        tmpDesc = desc;
+       last = desc->lastAddr;
+
        while (1) {
                tmpDesc->status = AR9170_OWN_BITS_HW;
                tmpDesc->ctrl = 0;
@@ -178,24 +180,28 @@ void dma_reclaim(struct dma_queue *q, struct dma_desc *desc)
 
                /* TODO : Exception handle */
 
-               if (desc->lastAddr == tmpDesc)
+               tmpDesc->lastAddr = tmpDesc;
+
+               if (tmpDesc == last)
                        break;
 
-               tmpDesc->lastAddr = desc->lastAddr;
                tmpDesc = tmpDesc->nextAddr;
        }
 
        /* 2. Next address of Last TD to be added = first TD */
-       desc->lastAddr->nextAddr = desc;
+       tmpDesc->nextAddr = desc;
+
+       /* Link first TD to self */
+       desc->lastAddr = q->terminator;
 
        /* 3. Copy first TD to be added to TTD */
        copy_dma_desc(&tdesc, desc);
 
-       /* 4. set first TD OWN bit to SW */
-       desc->status = AR9170_OWN_BITS_SW;
+       /* 4. Initialize new terminator */
+       clear_descriptor(desc);
 
        /* 5. Copy TTD to last TD */
-       tdesc.status &= (~AR9170_OWN_BITS);
+       tdesc.status = 0;
        copy_dma_desc((void *)q->terminator, (void *)&tdesc);
        q->terminator->status |= AR9170_OWN_BITS_HW;
 
@@ -241,14 +247,8 @@ void dma_put(struct dma_queue *q, struct dma_desc *desc)
        /* 3. Copy first TD to be added to TTD */
        copy_dma_desc(&tdesc, desc);
 
-       /* 4. set first TD OWN bit to SW */
-       desc->status = AR9170_OWN_BITS_SW;
-       desc->ctrl = 0;
-       desc->totalLen = 0;
-       desc->dataSize = 0;
-       desc->lastAddr = desc;
-       desc->nextAddr = desc;
-       desc->dataAddr = NULL;
+       /* 4. Initialize new terminator */
+       clear_descriptor(desc);
 
        /* 5. Copy TTD to last TD */
        tdesc.status &= (~AR9170_OWN_BITS);
index bad3b1266190a61dd96d94dc38e921b50ebb2627..a934687a9feaf1a10d87474e66e086732fa64c2b 100644 (file)
@@ -35,6 +35,7 @@ const struct carl9170_firmware_descriptor __section(fwdsc) carl9170fw_desc = {
        FILL(otus, OTUS,
             .feature_set = cpu_to_le32(BIT(CARL9170FW_DUMMY_FEATURE) |
                                        BIT(CARL9170FW_USB_RESP_EP2) |
+                                       BIT(CARL9170FW_RX_FILTER) |
 #ifdef CONFIG_CARL9170FW_USB_INIT_FIRMWARE
                                        BIT(CARL9170FW_USB_INIT_FIRMWARE) |
 # ifdef CONFIG_CARL9170FW_USB_UP_STREAM
@@ -46,6 +47,7 @@ const struct carl9170_firmware_descriptor __section(fwdsc) carl9170fw_desc = {
 #endif /* CONFIG_CARL9170FW_USB_INIT_FIRMWARE */
 #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
                                        BIT(CARL9170FW_COMMAND_PHY) |
+                                       BIT(CARL9170FW_PSM) |
 #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
 #ifdef CONFIG_CARL9170FW_SECURITY_ENGINE
                                        BIT(CARL9170FW_COMMAND_CAM) |
@@ -62,14 +64,10 @@ const struct carl9170_firmware_descriptor __section(fwdsc) carl9170fw_desc = {
 #ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT
                                        BIT(CARL9170FW_GPIO_INTERRUPT) |
 #endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */
-#ifdef CONFIG_CARL9170FW_PSM
-                                       BIT(CARL9170FW_PSM) |
-#endif /* CONFIG_CARL9170FW_PSM */
-                                       BIT(CARL9170FW_RX_FILTER) |
 #ifdef CONFIG_CARL9170FW_WOL
                                        BIT(CARL9170FW_WOL) |
 #endif /* CONFIG_CARL9170FW_WOL */
-                                          (0)),
+                                       (0)),
 
             .miniboot_size = cpu_to_le16(0),
             .tx_descs = AR9170_TX_BLOCK_NUMBER,
index d032c0f72da47ab9ed1ed054c4a38fd5f27600e4..0e7cbf2a23d572b614e095d6e65c5b2071c3b5a4 100644 (file)
@@ -30,7 +30,7 @@
 
 static bool length_check(struct dma_desc *desc)
 {
-       volatile struct carl9170_tx_superframe *super = DESC_PAYLOAD(desc);
+       volatile struct carl9170_tx_superframe *super = __get_super(desc);
 
        if (unlikely(desc->totalLen < sizeof(struct carl9170_tx_superdesc)))
                return false;
@@ -56,7 +56,7 @@ static void handle_download(void)
         * Under normal conditions, all completed descs should have
         * the AR9170_OWN_BITS_SE status flag set.
         * However there seems to be a undocumented case where the flag
-        * is _SW...
+        * is _SW ( handle_download_exception )
         */
 
        for_each_desc_not_bits(desc, &fw.pta.down_queue, AR9170_OWN_BITS_HW) {
@@ -69,12 +69,12 @@ static void handle_download(void)
                         * timeout mechanism.
                         */
 
+                       wlan_tx_complete(__get_super(desc), false);
                        dma_reclaim(&fw.pta.down_queue, desc);
                        down_trigger();
-                       continue;
+               } else {
+                       wlan_tx(desc);
                }
-
-               wlan_tx(desc);
        }
 
 #ifdef CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT
@@ -111,6 +111,40 @@ static void handle_upload(void)
 #endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */
 }
 
+static void handle_download_exception(void)
+{
+       struct dma_desc *desc, *target;
+
+       /* actually, the queue should be stopped by now? */
+       usb_stop_down_queue();
+
+       target = (void *)((get(AR9170_PTA_REG_DN_CURR_ADDRH) << 16) |
+                 get(AR9170_PTA_REG_DN_CURR_ADDRL));
+
+       /*
+        * Put "forgotten" packets from the head of the queue, back
+        * to the current position
+        */
+       __while_desc_bits(desc, &fw.pta.down_queue, AR9170_OWN_BITS_HW) {
+               if (desc == target)
+                       break;
+
+               dma_reclaim(&fw.pta.down_queue,
+                   dma_unlink_head(&fw.pta.down_queue));
+       }
+
+       __for_each_desc_continue(desc, &fw.pta.down_queue) {
+               if ((desc->status & AR9170_OWN_BITS) == AR9170_OWN_BITS_SW) {
+                       dma_fix_downqueue(desc);
+               }
+       }
+
+
+       usb_start_down_queue();
+
+       down_trigger();
+}
+
 /* handle interrupts from DMA chip */
 void handle_host_interface(void)
 {
@@ -129,5 +163,9 @@ void handle_host_interface(void)
 
        HANDLER(pta_int, AR9170_PTA_INT_FLAG_UP, handle_upload);
 
+       /* This is just guesswork and MAGIC */
+       pta_int = get(AR9170_PTA_REG_DMA_STATUS);
+       HANDLER(pta_int, 0x1, handle_download_exception);
+
 #undef HANDLER
 }
index b11f0489257068d3c21564c294e9835db30d2546..0653ae44dde34bb8be28d9061b014a8c7d298c6c 100644 (file)
@@ -71,14 +71,9 @@ static void init(void)
        orl(AR9170_MAC_REG_AFTER_PNP, 1);
 
        /* Init watch dog control flag */
-#ifdef CONFIG_CARL9170FW_WATCHDOG
        fw.watchdog_enable = 1;
 
        set(AR9170_TIMER_REG_WATCH_DOG, AR9170_WATCH_DOG_TIMER);
-#else
-       fw.watchdog_enable = 0;
-       set(AR9170_TIMER_REG_WATCH_DOG, 0xffff);
-#endif /* CONFIG_CARL9170FW_WATCHDOG */
 
 #ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT
        fw.cached_gpio_state.gpio = get(AR9170_GPIO_REG_PORT_DATA) &
index 8a9895914990d82817a86ddbb28c9d954ffd651b..10220481d3e8514e04c1ab1010dd73a81ae87538 100644 (file)
@@ -215,7 +215,6 @@ void rf_cmd(const struct carl9170_cmd *cmd, struct carl9170_rsp *resp)
        resp->rf_init_res.ret = cpu_to_le32(ret);
 }
 
-#ifdef CONFIG_CARL9170FW_PSM
 void rf_psm(void)
 {
        u32 bank3;
@@ -275,6 +274,5 @@ void rf_psm(void)
 
        set(0x1c58f0, bank3);
 }
-#endif /* CONFIG_CARL9170FW_PSM */
 
 #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
index 0e0b1dd144b27c4254b0f8fbd0d53278e296c849..b81b74f687941c330d872dc7f8974f7eccd6fbf2 100644 (file)
@@ -156,8 +156,8 @@ static struct carl9170_tx_status *wlan_get_tx_status_buffer(void)
 }
 
 /* generate _aggregated_ tx_status for the host */
-static void wlan_tx_complete(struct carl9170_tx_superframe *super,
-                            bool txs)
+void wlan_tx_complete(struct carl9170_tx_superframe *super,
+                     bool txs)
 {
        struct carl9170_tx_status *status;
 
@@ -169,6 +169,7 @@ static void wlan_tx_complete(struct carl9170_tx_superframe *super,
         */
        status->cookie = super->s.cookie;
        status->queue = super->s.queue;
+       super->s.cookie = 0;
 
        /*
         * This field holds the number of tries of the rate in
@@ -307,9 +308,9 @@ static void __wlan_tx(struct dma_desc *desc)
 # endif
 #else /* CONFIG_CARL9170FW_LOOPBACK */
 
-# if ((defined CONFIG_CARL9170FW_DEBUG) && (defined CONFIG_CARL9170FW_PSM))
+# ifdef CONFIG_CARL9170FW_DEBUG
        BUG_ON(fw.phy.psm.state != CARL9170_PSM_WAKE);
-# endif /* CONFIG_CARL9170FW_DEBUG && CONFIG_CARL9170FW_PSM */
+# endif /* CONFIG_CARL9170FW_DEBUG */
 
        /* insert desc into the right queue */
        dma_put(&fw.wlan.tx_queue[super->s.queue], desc);
@@ -355,16 +356,14 @@ static void _wlan_tx(struct dma_desc *desc)
 static bool wlan_tx_status(struct dma_queue *queue,
                           struct dma_desc *desc)
 {
-       struct ar9170_tx_frame *frame = DESC_PAYLOAD(desc);
        struct carl9170_tx_superframe *super = get_super(desc);
-       struct ieee80211_hdr *hdr = &super->f.data.i3e;
        unsigned int qidx = super->s.queue;
        bool txfail, success;
 
        success = true;
 
        /* update hangcheck */
-       fw.wlan.last_tx_desc_num[qidx] = 0;
+       fw.wlan.last_super_num[qidx] = 0;
 
        if (!!(desc->ctrl & AR9170_CTRL_FAIL)) {
                txfail = !!(desc->ctrl & AR9170_CTRL_TXFAIL);
@@ -380,7 +379,7 @@ static bool wlan_tx_status(struct dma_queue *queue,
                         * order.
                         */
 
-                       if (!frame->hdr.mac.ampdu) {
+                       if (!super->f.hdr.mac.ampdu) {
                                /*
                                 * 802.11 - 7.1.3.1.5.
                                 * set "Retry Field" for consecutive attempts
@@ -388,8 +387,8 @@ static bool wlan_tx_status(struct dma_queue *queue,
                                 * Note: For AMPDU see:
                                 * 802.11n 9.9.1.6 "Retransmit Procedures"
                                 */
-
-                               hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
+                               super->f.data.i3e.frame_control |=
+                                       cpu_to_le16(IEEE80211_FCTL_RETRY);
                        }
 
                        if (txfail) {
@@ -463,10 +462,9 @@ static bool wlan_tx_status(struct dma_queue *queue,
 static void handle_tx_completion(void)
 {
        struct dma_desc *desc;
-       unsigned int map = 0;
        int i;
 
-       for (i = 0; i < __AR9170_NUM_TX_QUEUES; i++) {
+       for (i = AR9170_TXQ_SPECIAL; i >= AR9170_TXQ0; i--) {
                __while_desc_bits(desc, &fw.wlan.tx_queue[i], AR9170_OWN_BITS_SW) {
                        if (!wlan_tx_status(&fw.wlan.tx_queue[i], desc)) {
                                /* termination requested. */
@@ -479,10 +477,8 @@ static void handle_tx_completion(void)
 
                wlan_tx_ampdu_end(i);
                if (!queue_empty(&fw.wlan.tx_queue[i]))
-                       map |= BIT(i);
-
+                       wlan_trigger(BIT(i));
        }
-       wlan_trigger(map);
 }
 
 void __hot wlan_tx(struct dma_desc *desc)
@@ -520,8 +516,9 @@ static void wlan_send_buffered_ba(void)
        if (!fw.wlan.ba_desc_available)
                return;
 
-       ctx = &fw.wlan.ba_cache[fw.wlan.ba_head_idx % CONFIG_CARL9170FW_BACK_REQS_NUM];
+       ctx = &fw.wlan.ba_cache[fw.wlan.ba_head_idx];
        fw.wlan.ba_head_idx++;
+       fw.wlan.ba_head_idx %= CONFIG_CARL9170FW_BACK_REQS_NUM;
 
        /* Format BlockAck */
        fw.wlan.ba_desc->status = 0;
@@ -535,8 +532,8 @@ static void wlan_send_buffered_ba(void)
                sizeof(struct ar9170_tx_hwdesc) +
                sizeof(struct ieee80211_ba);
 
-       baf->s.ri[0].tries = 3;
-       baf->s.queue = 0;
+       baf->s.ri[0].tries = 1;
+       baf->s.queue = AR9170_TXQ_VO;
        baf->f.hdr.length = sizeof(struct ieee80211_ba) + FCS_LEN;
 
        /* HW Duration / Backoff */
@@ -574,12 +571,9 @@ static struct carl9170_bar_ctx *wlan_get_bar_cache_buffer(void)
 {
        struct carl9170_bar_ctx *tmp;
 
-       /* expire oldest entry, if we ran out of ba_ctx' */
-       if (fw.wlan.ba_head_idx + CONFIG_CARL9170FW_BACK_REQS_NUM < fw.wlan.ba_tail_idx)
-               fw.wlan.ba_head_idx++;
-
-       tmp = &fw.wlan.ba_cache[fw.wlan.ba_tail_idx % CONFIG_CARL9170FW_BACK_REQS_NUM];
+       tmp = &fw.wlan.ba_cache[fw.wlan.ba_tail_idx];
        fw.wlan.ba_tail_idx++;
+       fw.wlan.ba_tail_idx %= CONFIG_CARL9170FW_BACK_REQS_NUM;
 
        return tmp;
 }
@@ -985,14 +979,10 @@ static void handle_pretbtt(void)
        fw.wlan.cab_flush_time = get_clock_counter();
 #endif /* CONFIG_CARL9170FW_CAB_QUEUE */
 
-#ifdef CONFIG_CARL9170FW_PSM
        rf_psm();
 
        send_cmd_to_host(4, CARL9170_RSP_PRETBTT, 0x00,
                         (uint8_t *) &fw.phy.psm.state);
-#else
-       send_cmd_to_host(0, CARL9170_RSP_PRETBTT, 0x00, NULL);
-#endif /* CONFIG_CARL9170FW_PSM */
 }
 
 static void handle_atim(void)
@@ -1099,12 +1089,18 @@ void handle_wlan(void)
 #undef HANDLER
 }
 
+enum {
+       CARL9170FW_TX_MAC_BUMP = 4,
+       CARL9170FW_TX_MAC_DEBUG = 6,
+       CARL9170FW_TX_MAC_RESET = 7,
+};
+
 static void wlan_check_hang(void)
 {
        struct dma_desc *desc;
-       unsigned int i;
+       int i;
 
-       for (i = 0; i < __AR9170_NUM_TX_QUEUES; i++) {
+       for (i = AR9170_TXQ_SPECIAL; i >= AR9170_TXQ0; i--) {
                if (queue_empty(&fw.wlan.tx_queue[i])) {
                        /* Nothing to do here... move along */
                        continue;
@@ -1114,10 +1110,10 @@ static void wlan_check_hang(void)
                desc = get_wlan_txq_addr(i);
 
                /* Stuck frame detection */
-               if (unlikely(desc == fw.wlan.last_tx_desc[i])) {
-                       fw.wlan.last_tx_desc_num[i]++;
+               if (unlikely(DESC_PAYLOAD(desc) == fw.wlan.last_super[i])) {
+                       fw.wlan.last_super_num[i]++;
 
-                       if (unlikely(fw.wlan.last_tx_desc_num[i] > 6)) {
+                       if (unlikely(fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_RESET)) {
                                /*
                                 * schedule MAC reset (aka OFF/ON => dead)
                                 *
@@ -1130,7 +1126,7 @@ static void wlan_check_hang(void)
                        }
 
 #ifdef CONFIG_CARL9170FW_DEBUG
-                       if (unlikely(fw.wlan.last_tx_desc_num[i] > 5)) {
+                       if (unlikely(fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_DEBUG)) {
                                /*
                                 * Sigh, the queue is almost certainly
                                 * dead. Dump the queue content to the
@@ -1143,7 +1139,7 @@ static void wlan_check_hang(void)
 #endif /* CONFIG_CARL9170FW_DEBUG */
 
 #ifdef CONFIG_CARL9170FW_DMA_QUEUE_BUMP
-                       if (unlikely(fw.wlan.last_tx_desc_num[i] > 3)) {
+                       if (unlikely(fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_BUMP)) {
                                /*
                                 * Hrrm, bump the queue a bit.
                                 * maybe this will get it going again.
@@ -1155,8 +1151,8 @@ static void wlan_check_hang(void)
 #endif /* CONFIG_CARL9170FW_DMA_QUEUE_BUMP */
                } else {
                        /* Nothing stuck */
-                       fw.wlan.last_tx_desc[i] = desc;
-                       fw.wlan.last_tx_desc_num[i] = 0;
+                       fw.wlan.last_super[i] = DESC_PAYLOAD(desc);
+                       fw.wlan.last_super_num[i] = 0;
                }
        }
 }
@@ -1179,13 +1175,15 @@ static void wlan_mac_reset(void)
        uint32_t ack_power;
        uint32_t rts_cts_tpc;
        uint32_t rts_cts_rate;
-       unsigned int i;
+       int i;
 
 #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
        uint32_t rx_BB;
 #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
 
+#ifdef CONFIG_CARL9170FW_NOISY_MAC_RESET
        INFO("MAC RESET");
+#endif /* CONFIG_CARL9170FW_NOISY_MAC_RESET */
 
        /* Save aggregation parameters */
        agg_wait_counter = get(AR9170_MAC_REG_AMPDU_FACTOR);
@@ -1255,11 +1253,34 @@ static void wlan_mac_reset(void)
 
        val = AR9170_DMA_TRIGGER_RXQ;
        /* Reinitialize all WLAN TX DMA queues. */
-       for (i = 0; i < __AR9170_NUM_TX_QUEUES; i++) {
+       for (i = AR9170_TXQ_SPECIAL; i >= AR9170_TXQ0; i--) {
                struct dma_desc *iter;
 
                __for_each_desc_bits(iter, &fw.wlan.tx_queue[i], AR9170_OWN_BITS_SW);
 
+               /* kill the stuck frame */
+               if (!is_terminator(&fw.wlan.tx_queue[i], iter) &&
+                   fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_RESET &&
+                   fw.wlan.last_super[i] == DESC_PAYLOAD(iter)) {
+                       struct carl9170_tx_superframe *super = get_super(iter);
+
+                       iter->status = AR9170_OWN_BITS_SW;
+                       /*
+                        * Mark the frame as failed.
+                        * The BAFAIL flag allows the frame to sail through
+                        * wlan_tx_status without much "unstuck" trouble.
+                        */
+                       iter->ctrl &= ~(AR9170_CTRL_FAIL);
+                       iter->ctrl |= AR9170_CTRL_BAFAIL;
+
+                       super->s.cnt = CARL9170_TX_MAX_RATE_TRIES;
+                       super->s.rix = CARL9170_TX_MAX_RETRY_RATES;
+
+                       fw.wlan.last_super_num[i] = 0;
+                       fw.wlan.last_super[i] = NULL;
+                       iter = iter->lastAddr->nextAddr;
+               }
+
                set_wlan_txq_dma_addr(i, (uint32_t) iter);
                if (!is_terminator(&fw.wlan.tx_queue[i], iter))
                        val |= BIT(i);
diff --git a/include/generated/defconfig b/include/generated/defconfig
deleted file mode 100644 (file)
index efb3c2d..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# CARL9170 Firmware
-# Sun May 23 02:34:08 2010
-#
-
-#
-# General
-#
-# CONFIG_CARL9170FW_MAKE_RELEASE is not set
-
-#
-# Selectable Hardware Options
-#
-# CONFIG_CARL9170FW_RX_FRAME_LEN_4096 is not set
-CONFIG_CARL9170FW_RX_FRAME_LEN_8192=y
-# CONFIG_CARL9170FW_RX_FRAME_LEN_16384 is not set
-# CONFIG_CARL9170FW_RX_FRAME_LEN_32768 is not set
-CONFIG_CARL9170FW_RX_FRAME_LEN=8192
-CONFIG_CARL9170FW_WATCHDOG=y
-CONFIG_CARL9170FW_GPIO_INTERRUPT=y
-CONFIG_CARL9170FW_SECURITY_ENGINE=y
-CONFIG_CARL9170FW_RADIO_FUNCTIONS=y
-
-#
-# 802.11 Firmware Features
-#
-CONFIG_CARL9170FW_HANDLE_BACK_REQ=y
-CONFIG_CARL9170FW_BACK_REQS_NUM=4
-CONFIG_CARL9170FW_CAB_QUEUE=y
-
-#
-# USB Firmware Configuration Settings
-#
-CONFIG_CARL9170FW_USB_STANDARD_CMDS=y
-CONFIG_CARL9170FW_USB_INIT_FIRMWARE=y
-CONFIG_CARL9170FW_USB_UP_STREAM=y
-# CONFIG_CARL9170FW_USB_DN_STREAM is not set
-# CONFIG_CARL9170FW_USB_WATCHDOG is not set
-CONFIG_CARL9170FW_DEBUG_USB=y
-
-#
-# Experimental, Unstable & Testing Extensions
-#
-CONFIG_CARL9170FW_PRINTF=y
-# CONFIG_CARL9170FW_LOOPBACK is not set
-# CONFIG_CARL9170FW_WATCHDOG_BUTTON is not set
-CONFIG_CARL9170FW_EXPERIMENTAL=y
-CONFIG_CARL9170FW_PSM=y
-CONFIG_CARL9170FW_DELAYED_TX=y
-# CONFIG_CARL9170FW_BROKEN_FEATURES is not set
-
-#
-# Build Options
-#
-CONFIG_CARL9170FW_AGGRESSIVE_CFLAGS=y
-# CONFIG_CARL9170FW_BUILD_MINIBOOT is not set
-
-#
-# Firmware Tools
-#
-# CONFIG_CARL9170FW_BUILD_TOOLS is not set
index 94438b51630254fea8cb236dd212c71d842605e9..9cfe36680097c7f773a344514494cddb7987a34a 100644 (file)
@@ -104,7 +104,7 @@ struct carl9170fw_desc_head {
        (sizeof(struct carl9170fw_desc_head))
 
 #define CARL9170FW_OTUS_DESC_MIN_VER           6
-#define CARL9170FW_OTUS_DESC_CUR_VER           6
+#define CARL9170FW_OTUS_DESC_CUR_VER           7
 struct carl9170fw_otus_desc {
        struct carl9170fw_desc_head head;
        __le32 feature_set;
index bde4244011aff2021c6c2e8d5532cd953d52ce06..261f8935107006c9f5915aeb6b398690ce51ebae 100644 (file)
 
 #define AR9170_MAC_REG_DMA_WLAN_STATUS         (AR9170_MAC_REG_BASE + 0xd38)
 #define        AR9170_MAC_REG_DMA_STATUS               (AR9170_MAC_REG_BASE + 0xd3c)
-
+#define AR9170_MAC_REG_DMA_TXQ_LAST_ADDR       (AR9170_MAC_REG_BASE + 0xd40)
+#define        AR9170_MAC_REG_DMA_TXQ0_LAST_ADDR       (AR9170_MAC_REG_BASE + 0xd40)
+#define        AR9170_MAC_REG_DMA_TXQ1_LAST_ADDR       (AR9170_MAC_REG_BASE + 0xd44)
+#define        AR9170_MAC_REG_DMA_TXQ2_LAST_ADDR       (AR9170_MAC_REG_BASE + 0xd48)
+#define        AR9170_MAC_REG_DMA_TXQ3_LAST_ADDR       (AR9170_MAC_REG_BASE + 0xd4c)
+#define        AR9170_MAC_REG_DMA_TXQ4_LAST_ADDR       (AR9170_MAC_REG_BASE + 0xd50)
+#define        AR9170_MAC_REG_DMA_TXQ0Q1_LEN           (AR9170_MAC_REG_BASE + 0xd54)
+#define        AR9170_MAC_REG_DMA_TXQ2Q3_LEN           (AR9170_MAC_REG_BASE + 0xd58)
+#define        AR9170_MAC_REG_DMA_TXQ4_LEN             (AR9170_MAC_REG_BASE + 0xd5c)
+
+#define AR9170_MAC_REG_DMA_TXQX_LAST_ADDR      (AR9170_MAC_REG_BASE + 0xd74)
+#define AR9170_MAC_REG_DMA_TXQX_FAIL_ADDR      (AR9170_MAC_REG_BASE + 0xd78)
 #define        AR9170_MAC_REG_TXRX_MPI                 (AR9170_MAC_REG_BASE + 0xd7c)
 #define                AR9170_MAC_TXRX_MPI_TX_MPI_MASK         0x0000000f
 #define                AR9170_MAC_TXRX_MPI_TX_TO_MASK          0x0000fff0
index 15095c035169c71c2f0b0576329d50e45be3e004..e3afc9564e67a66b8a197f12955989c889c5cdc6 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __CARL9170_SHARED_VERSION_H
 #define __CARL9170_SHARED_VERSION_H
 #define CARL9170FW_VERSION_YEAR 11
-#define CARL9170FW_VERSION_MONTH 1
-#define CARL9170FW_VERSION_DAY 22
-#define CARL9170FW_VERSION_GIT "1.9.2"
+#define CARL9170FW_VERSION_MONTH 3
+#define CARL9170FW_VERSION_DAY 4
+#define CARL9170FW_VERSION_GIT "1.9.3"
 #endif /* __CARL9170_SHARED_VERSION_H */
index 16b0364331f06484b97d231b5594f75fb4bc0808..ea17995b32f4ef60ac082e49e0f64188c8ad2652 100644 (file)
@@ -404,16 +404,6 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
               (t->DAidx & 0xc0) >> 6;
 }
 
-enum ar9170_txq {
-       AR9170_TXQ_BE,
-
-       AR9170_TXQ_VI,
-       AR9170_TXQ_VO,
-       AR9170_TXQ_BK,
-
-       __AR9170_NUM_TXQ,
-};
-
 /*
  * This is an workaround for several undocumented bugs.
  * Don't mess with the QoS/AC <-> HW Queue map, if you don't
@@ -431,7 +421,14 @@ enum ar9170_txq {
  * result, this makes the device pretty much useless
  * for any serious 802.11n setup.
  */
-static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 2, 1, 0, 3 };
+enum ar9170_txq {
+       AR9170_TXQ_BK = 0,      /* TXQ0 */
+       AR9170_TXQ_BE,          /* TXQ1 */
+       AR9170_TXQ_VI,          /* TXQ2 */
+       AR9170_TXQ_VO,          /* TXQ3 */
+
+       __AR9170_NUM_TXQ,
+};
 
 #define        AR9170_TXQ_DEPTH                        32
 
index d4774de5c95395487cd80d76efeedf3b58f9a9c8..ec97502038f0e5a3c8c68f1c35ae6c2e901d95ce 100644 (file)
@@ -188,7 +188,7 @@ int carlu_tx(struct carlu *ar, struct frame *frame)
 
        txp->s.len = cpu_to_le16(frame->len);
 
-       queue = ar9170_qmap[frame->queue % ARRAY_SIZE(ar9170_qmap)];
+       queue = (frame->queue % __AR9170_NUM_TXQ);
 
        SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, txp->s.misc, queue);