Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
[cascardo/linux.git] / drivers / net / wireless / iwlwifi / iwl-trans-pcie-int.h
index 561865f..1c2fe87 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/skbuff.h>
+#include <linux/wait.h>
 #include <linux/pci.h>
 
 #include "iwl-fh.h"
@@ -40,6 +41,7 @@
 #include "iwl-trans.h"
 #include "iwl-debug.h"
 #include "iwl-io.h"
+#include "iwl-op-mode.h"
 
 struct iwl_tx_queue;
 struct iwl_queue;
@@ -48,6 +50,12 @@ struct iwl_host_cmd;
 /*This file includes the declaration that are internal to the
  * trans_pcie layer */
 
+struct iwl_rx_mem_buffer {
+       dma_addr_t page_dma;
+       struct page *page;
+       struct list_head list;
+};
+
 /**
  * struct isr_statistics - interrupt statistics
  *
@@ -108,6 +116,26 @@ struct iwl_dma_ptr {
        size_t size;
 };
 
+/**
+ * iwl_queue_inc_wrap - increment queue index, wrap back to beginning
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (must be power of 2)
+ */
+static inline int iwl_queue_inc_wrap(int index, int n_bd)
+{
+       return ++index & (n_bd - 1);
+}
+
+/**
+ * iwl_queue_dec_wrap - decrement queue index, wrap back to end
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (must be power of 2)
+ */
+static inline int iwl_queue_dec_wrap(int index, int n_bd)
+{
+       return --index & (n_bd - 1);
+}
+
 /*
  * This queue number is required for proper operation
  * because the ucode will stop/start the scheduler as
@@ -168,6 +196,7 @@ struct iwl_queue {
  * @meta: array of meta data for each command/tx buffer
  * @dma_addr_cmd: physical address of cmd/tx buffer array
  * @txb: array of per-TFD driver data
+ * lock: queue lock
  * @time_stamp: time (in jiffies) of last read_ptr change
  * @need_update: indicates need to update read/write index
  * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
@@ -186,6 +215,7 @@ struct iwl_tx_queue {
        struct iwl_device_cmd **cmd;
        struct iwl_cmd_meta *meta;
        struct sk_buff **skbs;
+       spinlock_t lock;
        unsigned long time_stamp;
        u8 need_update;
        u8 sched_retry;
@@ -201,6 +231,7 @@ struct iwl_tx_queue {
  * @rxq: all the RX queue data
  * @rx_replenish: work that will be called when buffers need to be allocated
  * @trans: pointer to the generic transport area
+ * @irq - the irq number for the device
  * @irq_requested: true when the irq has been requested
  * @scd_base_addr: scheduler sram base address in SRAM
  * @scd_bc_tbls: pointer to the byte count table of the scheduler
@@ -214,6 +245,10 @@ struct iwl_tx_queue {
  * queue_stop_count: tracks what SW queue is stopped
  * @pci_dev: basic pci-network driver stuff
  * @hw_base: pci hardware address support
+ * @ucode_write_complete: indicates that the ucode has been copied.
+ * @ucode_write_waitq: wait queue for uCode load
+ * @status - transport specific status flags
+ * @cmd_queue - command queue number
  */
 struct iwl_trans_pcie {
        struct iwl_rx_queue rxq;
@@ -230,6 +265,8 @@ struct iwl_trans_pcie {
        struct tasklet_struct irq_tasklet;
        struct isr_statistics isr_stats;
 
+       unsigned int irq;
+       spinlock_t irq_lock;
        u32 inta_mask;
        u32 scd_base_addr;
        struct iwl_dma_ptr scd_bc_tbls;
@@ -249,6 +286,13 @@ struct iwl_trans_pcie {
        /* PCI bus related data */
        struct pci_dev *pci_dev;
        void __iomem *hw_base;
+
+       bool ucode_write_complete;
+       wait_queue_head_t ucode_write_waitq;
+       unsigned long status;
+       u8 cmd_queue;
+       u8 n_no_reclaim_cmds;
+       u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS];
 };
 
 #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
@@ -283,7 +327,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans,
 int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id);
 int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
 void iwl_tx_cmd_complete(struct iwl_trans *trans,
-                        struct iwl_rx_mem_buffer *rxb, int handler_status);
+                        struct iwl_rx_cmd_buffer *rxb, int handler_status);
 void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
                                           struct iwl_tx_queue *txq,
                                           u16 byte_cnt);
@@ -316,7 +360,8 @@ void iwl_dump_csr(struct iwl_trans *trans);
 ******************************************************/
 static inline void iwl_disable_interrupts(struct iwl_trans *trans)
 {
-       clear_bit(STATUS_INT_ENABLED, &trans->shrd->status);
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       clear_bit(STATUS_INT_ENABLED, &trans_pcie->status);
 
        /* disable interrupts from uCode/NIC to host */
        iwl_write32(trans, CSR_INT_MASK, 0x00000000);
@@ -330,14 +375,19 @@ static inline void iwl_disable_interrupts(struct iwl_trans *trans)
 
 static inline void iwl_enable_interrupts(struct iwl_trans *trans)
 {
-       struct iwl_trans_pcie *trans_pcie =
-               IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
        IWL_DEBUG_ISR(trans, "Enabling interrupts\n");
-       set_bit(STATUS_INT_ENABLED, &trans->shrd->status);
+       set_bit(STATUS_INT_ENABLED, &trans_pcie->status);
        iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
 }
 
+static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
+{
+       IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
+       iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
+}
+
 /*
  * we have 8 bits used like this:
  *
@@ -363,7 +413,7 @@ static inline u8 iwl_get_queue_ac(struct iwl_tx_queue *txq)
 }
 
 static inline void iwl_wake_queue(struct iwl_trans *trans,
-                                 struct iwl_tx_queue *txq, const char *msg)
+                                 struct iwl_tx_queue *txq)
 {
        u8 queue = txq->swq_id;
        u8 ac = queue & 3;
@@ -373,20 +423,20 @@ static inline void iwl_wake_queue(struct iwl_trans *trans,
 
        if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) {
                if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) {
-                       iwl_wake_sw_queue(priv(trans), ac);
-                       IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s",
-                                           hwq, ac, msg);
+                       iwl_op_mode_queue_not_full(trans->op_mode, ac);
+                       IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d",
+                                           hwq, ac);
                } else {
-                       IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d"
-                                           " stop count %d. %s",
-                                           hwq, ac, atomic_read(&trans_pcie->
-                                           queue_stop_count[ac]), msg);
+                       IWL_DEBUG_TX_QUEUES(trans,
+                               "Don't wake hwq %d ac %d stop count %d",
+                               hwq, ac,
+                               atomic_read(&trans_pcie->queue_stop_count[ac]));
                }
        }
 }
 
 static inline void iwl_stop_queue(struct iwl_trans *trans,
-                                 struct iwl_tx_queue *txq, const char *msg)
+                                 struct iwl_tx_queue *txq)
 {
        u8 queue = txq->swq_id;
        u8 ac = queue & 3;
@@ -396,35 +446,23 @@ static inline void iwl_stop_queue(struct iwl_trans *trans,
 
        if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) {
                if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) {
-                       iwl_stop_sw_queue(priv(trans), ac);
-                       IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d"
-                                           " stop count %d. %s",
-                                           hwq, ac, atomic_read(&trans_pcie->
-                                           queue_stop_count[ac]), msg);
+                       iwl_op_mode_queue_full(trans->op_mode, ac);
+                       IWL_DEBUG_TX_QUEUES(trans,
+                               "Stop hwq %d ac %d stop count %d",
+                               hwq, ac,
+                               atomic_read(&trans_pcie->queue_stop_count[ac]));
                } else {
-                       IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d"
-                                           " stop count %d. %s",
-                                           hwq, ac, atomic_read(&trans_pcie->
-                                           queue_stop_count[ac]), msg);
+                       IWL_DEBUG_TX_QUEUES(trans,
+                               "Don't stop hwq %d ac %d stop count %d",
+                               hwq, ac,
+                               atomic_read(&trans_pcie->queue_stop_count[ac]));
                }
        } else {
-               IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s",
-                                   hwq, msg);
+               IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped",
+                                   hwq);
        }
 }
 
-#ifdef ieee80211_stop_queue
-#undef ieee80211_stop_queue
-#endif
-
-#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
-
-#ifdef ieee80211_wake_queue
-#undef ieee80211_wake_queue
-#endif
-
-#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
-
 static inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie,
                                        int txq_id)
 {