carl9170 firmware: handle download queue exceptions
[carl9170fw.git] / carlfw / include / dma.h
index 079b3b7f227d0d4849624bbc6603b968805036cc..11a760dfc98139cb68c921d188d1cc19c8b71941 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (c) 2000-2005 ZyDAS Technology Corporation
  * Copyright (c) 2007-2009 Atheros Communications, Inc.
  * Copyright   2009    Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, 2010 Christian Lamparter <chunkeey@googlemail.com>
+ * Copyright 2009-2011  Christian Lamparter <chunkeey@googlemail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,21 +44,15 @@ struct dma_desc {
                void *dataAddr;
        } __packed;
        struct dma_desc *nextAddr;      /* Next TD address */
-} __packed;
+} __packed __aligned(4);
 
-/* (Up, Dn, 5x Tx, Rx), USB Int, (5x delayed Tx + retry), CAB, BA */
-#define AR9170_TERMINATOR_NUMBER_B     8
+/* Up, Dn, 5x Tx, retry, Rx, [USB Int], (CAB), (BA) */
+#define AR9170_TERMINATOR_NUMBER_B     9
 
 #define AR9170_TERMINATOR_NUMBER_INT   1
 
-#ifdef CONFIG_CARL9170FW_DELAYED_TX
-#define AR9170_TERMINATOR_NUMBER_DELAY 6
-#else
-#define AR9170_TERMINATOR_NUMBER_DELAY 0
-#endif /* CONFIG_CARL9170FW_DELAYED_TX */
-
 #ifdef CONFIG_CARL9170FW_CAB_QUEUE
-#define AR9170_TERMINATOR_NUMBER_CAB   1
+#define AR9170_TERMINATOR_NUMBER_CAB   CARL9170_INTF_NUM
 #else
 #define AR9170_TERMINATOR_NUMBER_CAB   0
 #endif /* CONFIG_CARL9170FW_CAB_QUEUE */
@@ -70,7 +64,6 @@ struct dma_desc {
 #endif /* CONFIG_CARL9170FW_HANDLE_BACK_REQ */
 #define AR9170_TERMINATOR_NUMBER (AR9170_TERMINATOR_NUMBER_B + \
                                  AR9170_TERMINATOR_NUMBER_INT + \
-                                 AR9170_TERMINATOR_NUMBER_DELAY + \
                                  AR9170_TERMINATOR_NUMBER_CAB + \
                                  AR9170_TERMINATOR_NUMBER_BA)
 
@@ -121,11 +114,11 @@ struct carl9170_sram_reserved {
  *                             |  - Up (to USB host)
  *                             |  - Down (from USB host)
  *                             |  - TX (5x, to wifi)
+ *                             |  - AMPDU TX retry
  *                             |  - RX (from wifi)
  *                             |  - CAB Queue
  *                             |  - FW cmd & req descriptor
  *                             |  - BlockAck descriptor
- *                             |  - Delayed TX (5x)
  *                             | total: AR9170_TERMINATOR_NUMBER
  *                             +--
  *                             | block descriptors (dma_desc)
@@ -147,7 +140,6 @@ struct carl9170_sram_reserved {
  * 0x18000
  */
 
-#define AR9170_SRAM_SIZE               0x18000
 #define CARL9170_SRAM_RESERVED         (sizeof(struct carl9170_sram_reserved))
 
 #define AR9170_FRAME_MEMORY_SIZE       (AR9170_SRAM_SIZE - CARL9170_SRAM_RESERVED)
@@ -170,45 +162,46 @@ struct ar9170_data_block {
 struct ar9170_dma_memory {
        struct dma_desc                 terminator[AR9170_TERMINATOR_NUMBER];
        struct dma_desc                 block[AR9170_BLOCK_NUMBER];
-       struct ar9170_data_block        data[AR9170_BLOCK_NUMBER] __attribute__((aligned(BLOCK_ALIGNMENT)));
-       struct carl9170_sram_reserved   reserved __attribute__((aligned(BLOCK_ALIGNMENT)));
+       struct ar9170_data_block        data[AR9170_BLOCK_NUMBER] __aligned(BLOCK_ALIGNMENT);
+       struct carl9170_sram_reserved   reserved __aligned(BLOCK_ALIGNMENT);
 };
 
 extern struct ar9170_dma_memory dma_mem;
 
-#define AR9170_DOWN_BLOCK_RATIO     2
-#define AR9170_RX_BLOCK_RATIO       1
+#define AR9170_DOWN_BLOCK_RATIO        2
+#define AR9170_RX_BLOCK_RATIO  1
 /* Tx 16*2 = 32 packets => 32*(5*320) */
-#define AR9170_TX_BLOCK_NUMBER     (AR9170_BLOCK_NUMBER * AR9170_DOWN_BLOCK_RATIO / \
-                                  (AR9170_RX_BLOCK_RATIO + AR9170_DOWN_BLOCK_RATIO))
-#define AR9170_RX_BLOCK_NUMBER     (AR9170_BLOCK_NUMBER - AR9170_TX_BLOCK_NUMBER)
+#define AR9170_TX_BLOCK_NUMBER (AR9170_BLOCK_NUMBER * AR9170_DOWN_BLOCK_RATIO / \
+                               (AR9170_RX_BLOCK_RATIO + AR9170_DOWN_BLOCK_RATIO))
+#define AR9170_RX_BLOCK_NUMBER (AR9170_BLOCK_NUMBER - AR9170_TX_BLOCK_NUMBER)
 
 /* Error code */
-#define AR9170_ERR_FS_BIT           1
-#define AR9170_ERR_LS_BIT           2
-#define AR9170_ERR_OWN_BITS         3
-#define AR9170_ERR_DATA_SIZE        4
-#define AR9170_ERR_TOTAL_LEN        5
-#define AR9170_ERR_DATA             6
-#define AR9170_ERR_SEQ              7
-#define AR9170_ERR_LEN              8
+#define AR9170_ERR_FS_BIT      1
+#define AR9170_ERR_LS_BIT      2
+#define AR9170_ERR_OWN_BITS    3
+#define AR9170_ERR_DATA_SIZE   4
+#define AR9170_ERR_TOTAL_LEN   5
+#define AR9170_ERR_DATA                6
+#define AR9170_ERR_SEQ         7
+#define AR9170_ERR_LEN         8
 
 /* Status bits definitions */
 /* Own bits definitions */
-#define AR9170_OWN_BITS_MASK        0x3
-#define AR9170_OWN_BITS_SW          0x0
-#define AR9170_OWN_BITS_HW          0x1
-#define AR9170_OWN_BITS_SE          0x2
+#define AR9170_OWN_BITS                0x3
+#define AR9170_OWN_BITS_S      0
+#define AR9170_OWN_BITS_SW     0x0
+#define AR9170_OWN_BITS_HW     0x1
+#define AR9170_OWN_BITS_SE     0x2
 
 /* Control bits definitions */
 #define AR9170_CTRL_TXFAIL     1
 #define AR9170_CTRL_BAFAIL     2
-#define AR9170_CTRL_FAIL_MASK  (AR9170_CTRL_TXFAIL | AR9170_CTRL_BAFAIL)
+#define AR9170_CTRL_FAIL       (AR9170_CTRL_TXFAIL | AR9170_CTRL_BAFAIL)
 
 /* First segament bit */
-#define AR9170_CTRL_LS_BIT               0x100
+#define AR9170_CTRL_LS_BIT     0x100
 /* Last segament bit */
-#define AR9170_CTRL_FS_BIT               0x200
+#define AR9170_CTRL_FS_BIT     0x200
 
 struct dma_queue {
        struct dma_desc *head;
@@ -222,9 +215,11 @@ 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);
-void queue_dump(void);
-void wlan_txq_hangfix(const unsigned int queue);
+
+static inline __inline bool is_terminator(struct dma_queue *q, struct dma_desc *desc)
+{
+       return q->terminator == desc;
+}
 
 static inline __inline bool queue_empty(struct dma_queue *q)
 {
@@ -240,7 +235,7 @@ static inline __inline struct dma_desc *dma_dequeue_bits(struct dma_queue *q,
 {
        struct dma_desc *desc = NULL;
 
-       if ((q->head->status & AR9170_OWN_BITS_MASK) == bits)
+       if ((q->head->status & AR9170_OWN_BITS) == bits)
                desc = dma_unlink_head(q);
 
        return desc;
@@ -252,7 +247,7 @@ static inline __inline struct dma_desc *dma_dequeue_not_bits(struct dma_queue *q
        struct dma_desc *desc = NULL;
 
        /* AR9170_OWN_BITS_HW will be filtered out here too. */
-       if ((q->head->status & AR9170_OWN_BITS_MASK) != bits)
+       if ((q->head->status & AR9170_OWN_BITS) != bits)
                desc = dma_unlink_head(q);
 
        return desc;
@@ -270,15 +265,19 @@ static inline __inline struct dma_desc *dma_dequeue_not_bits(struct dma_queue *q
 #define __for_each_desc_bits(desc, queue, bits)                                \
        for (desc = (queue)->head;                                      \
             (desc != (queue)->terminator &&                            \
-            (desc->status & AR9170_OWN_BITS_MASK) == bits);            \
+            (desc->status & AR9170_OWN_BITS) == bits);                 \
             desc = desc->lastAddr->nextAddr)
 
 #define __while_desc_bits(desc, queue, bits)                           \
        for (desc = (queue)->head;                                      \
             (!queue_empty(queue) &&                                    \
-            (desc->status & AR9170_OWN_BITS_MASK) == bits);            \
+            (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,10 +310,19 @@ static inline __inline unsigned int queue_len(struct dma_queue *q)
 static inline __inline void dma_rearm(struct dma_desc *desc)
 {
        /* Set OWN bit to HW */
-       desc->status = ((desc->status & (~AR9170_OWN_BITS_MASK)) |
+       desc->status = ((desc->status & (~AR9170_OWN_BITS)) |
                        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;