ath10k: don't enable interrupts for the diagnostic window
[cascardo/linux.git] / drivers / net / wireless / ath / ath10k / ce.c
index d185dc0..09ef03e 100644 (file)
@@ -260,7 +260,6 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar,
        ath10k_pci_write32(ar, ce_ctrl_addr + HOST_IS_ADDRESS, mask);
 }
 
-
 /*
  * Guts of ath10k_ce_send, used by both ath10k_ce_send and
  * ath10k_ce_sendlist_send.
@@ -284,13 +283,9 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
        int ret = 0;
 
        if (nbytes > ce_state->src_sz_max)
-               ath10k_warn("%s: send more we can (nbytes: %d, max: %d)\n",
+               ath10k_warn(ar, "%s: send more we can (nbytes: %d, max: %d)\n",
                            __func__, nbytes, ce_state->src_sz_max);
 
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return ret;
-
        if (unlikely(CE_RING_DELTA(nentries_mask,
                                   write_index, sw_index - 1) <= 0)) {
                ret = -ENOSR;
@@ -325,7 +320,6 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
 
        src_ring->write_index = write_index;
 exit:
-       ath10k_pci_sleep(ar);
        return ret;
 }
 
@@ -390,49 +384,56 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe)
        return delta;
 }
 
-int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state,
-                              void *per_recv_context,
-                              u32 buffer)
+int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe)
 {
-       struct ath10k_ce_ring *dest_ring = ce_state->dest_ring;
-       u32 ctrl_addr = ce_state->ctrl_addr;
-       struct ath10k *ar = ce_state->ar;
+       struct ath10k *ar = pipe->ar;
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+       struct ath10k_ce_ring *dest_ring = pipe->dest_ring;
        unsigned int nentries_mask = dest_ring->nentries_mask;
-       unsigned int write_index;
-       unsigned int sw_index;
-       int ret;
+       unsigned int write_index = dest_ring->write_index;
+       unsigned int sw_index = dest_ring->sw_index;
 
-       spin_lock_bh(&ar_pci->ce_lock);
-       write_index = dest_ring->write_index;
-       sw_index = dest_ring->sw_index;
+       lockdep_assert_held(&ar_pci->ce_lock);
 
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               goto out;
+       return CE_RING_DELTA(nentries_mask, write_index, sw_index - 1);
+}
 
-       if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) > 0) {
-               struct ce_desc *base = dest_ring->base_addr_owner_space;
-               struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index);
+int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr)
+{
+       struct ath10k *ar = pipe->ar;
+       struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+       struct ath10k_ce_ring *dest_ring = pipe->dest_ring;
+       unsigned int nentries_mask = dest_ring->nentries_mask;
+       unsigned int write_index = dest_ring->write_index;
+       unsigned int sw_index = dest_ring->sw_index;
+       struct ce_desc *base = dest_ring->base_addr_owner_space;
+       struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index);
+       u32 ctrl_addr = pipe->ctrl_addr;
 
-               /* Update destination descriptor */
-               desc->addr    = __cpu_to_le32(buffer);
-               desc->nbytes = 0;
+       lockdep_assert_held(&ar_pci->ce_lock);
 
-               dest_ring->per_transfer_context[write_index] =
-                                                       per_recv_context;
+       if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) == 0)
+               return -EIO;
 
-               /* Update Destination Ring Write Index */
-               write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
-               ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index);
-               dest_ring->write_index = write_index;
-               ret = 0;
-       } else {
-               ret = -EIO;
-       }
-       ath10k_pci_sleep(ar);
+       desc->addr = __cpu_to_le32(paddr);
+       desc->nbytes = 0;
+
+       dest_ring->per_transfer_context[write_index] = ctx;
+       write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
+       ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index);
+       dest_ring->write_index = write_index;
+
+       return 0;
+}
+
+int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr)
+{
+       struct ath10k *ar = pipe->ar;
+       struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+       int ret;
 
-out:
+       spin_lock_bh(&ar_pci->ce_lock);
+       ret = __ath10k_ce_rx_post_buf(pipe, ctx, paddr);
        spin_unlock_bh(&ar_pci->ce_lock);
 
        return ret;
@@ -588,7 +589,6 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
        unsigned int sw_index = src_ring->sw_index;
        struct ce_desc *sdesc, *sbase;
        unsigned int read_index;
-       int ret;
 
        if (src_ring->hw_index == sw_index) {
                /*
@@ -599,20 +599,17 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
                 * value of the HW index has become stale.
                 */
 
-               ret = ath10k_pci_wake(ar);
-               if (ret)
-                       return ret;
-
-               src_ring->hw_index =
-                       ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
-               src_ring->hw_index &= nentries_mask;
+               read_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
+               if (read_index == 0xffffffff)
+                       return -ENODEV;
 
-               ath10k_pci_sleep(ar);
+               read_index &= nentries_mask;
+               src_ring->hw_index = read_index;
        }
 
        read_index = src_ring->hw_index;
 
-       if ((read_index == sw_index) || (read_index == 0xffffffff))
+       if (read_index == sw_index)
                return -EIO;
 
        sbase = src_ring->shadow_base;
@@ -728,11 +725,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
        struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
        u32 ctrl_addr = ce_state->ctrl_addr;
-       int ret;
-
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return;
 
        spin_lock_bh(&ar_pci->ce_lock);
 
@@ -757,7 +749,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
        ath10k_ce_engine_int_status_clear(ar, ctrl_addr, CE_WATERMARK_MASK);
 
        spin_unlock_bh(&ar_pci->ce_lock);
-       ath10k_pci_sleep(ar);
 }
 
 /*
@@ -768,13 +759,9 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
 
 void ath10k_ce_per_engine_service_any(struct ath10k *ar)
 {
-       int ce_id, ret;
+       int ce_id;
        u32 intr_summary;
 
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return;
-
        intr_summary = CE_INTERRUPT_SUMMARY(ar);
 
        for (ce_id = 0; intr_summary && (ce_id < CE_COUNT); ce_id++) {
@@ -786,8 +773,6 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar)
 
                ath10k_ce_per_engine_service(ar, ce_id);
        }
-
-       ath10k_pci_sleep(ar);
 }
 
 /*
@@ -797,16 +782,11 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar)
  *
  * Called with ce_lock held.
  */
-static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state,
-                                               int disable_copy_compl_intr)
+static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state)
 {
        u32 ctrl_addr = ce_state->ctrl_addr;
        struct ath10k *ar = ce_state->ar;
-       int ret;
-
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return;
+       bool disable_copy_compl_intr = ce_state->attr_flags & CE_ATTR_DIS_INTR;
 
        if ((!disable_copy_compl_intr) &&
            (ce_state->send_cb || ce_state->recv_cb))
@@ -815,17 +795,11 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state,
                ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr);
 
        ath10k_ce_watermark_intr_disable(ar, ctrl_addr);
-
-       ath10k_pci_sleep(ar);
 }
 
 int ath10k_ce_disable_interrupts(struct ath10k *ar)
 {
-       int ce_id, ret;
-
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return ret;
+       int ce_id;
 
        for (ce_id = 0; ce_id < CE_COUNT; ce_id++) {
                u32 ctrl_addr = ath10k_ce_base_address(ce_id);
@@ -835,34 +809,19 @@ int ath10k_ce_disable_interrupts(struct ath10k *ar)
                ath10k_ce_watermark_intr_disable(ar, ctrl_addr);
        }
 
-       ath10k_pci_sleep(ar);
-
        return 0;
 }
 
-void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,
-                               void (*send_cb)(struct ath10k_ce_pipe *),
-                               int disable_interrupts)
+void ath10k_ce_enable_interrupts(struct ath10k *ar)
 {
-       struct ath10k *ar = ce_state->ar;
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+       int ce_id;
 
-       spin_lock_bh(&ar_pci->ce_lock);
-       ce_state->send_cb = send_cb;
-       ath10k_ce_per_engine_handler_adjust(ce_state, disable_interrupts);
-       spin_unlock_bh(&ar_pci->ce_lock);
-}
-
-void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state,
-                               void (*recv_cb)(struct ath10k_ce_pipe *))
-{
-       struct ath10k *ar = ce_state->ar;
-       struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-
-       spin_lock_bh(&ar_pci->ce_lock);
-       ce_state->recv_cb = recv_cb;
-       ath10k_ce_per_engine_handler_adjust(ce_state, 0);
-       spin_unlock_bh(&ar_pci->ce_lock);
+       /* Skip the last copy engine, CE7 the diagnostic window, as that
+        * uses polling and isn't initialized for interrupts.
+        */
+       for (ce_id = 0; ce_id < CE_COUNT - 1; ce_id++)
+               ath10k_ce_per_engine_handler_adjust(&ar_pci->ce_states[ce_id]);
 }
 
 static int ath10k_ce_init_src_ring(struct ath10k *ar,
@@ -895,7 +854,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
        ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0);
        ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
 
-       ath10k_dbg(ATH10K_DBG_BOOT,
+       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                   "boot init ce src ring id %d entries %d base_addr %p\n",
                   ce_id, nentries, src_ring->base_addr_owner_space);
 
@@ -929,7 +888,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
        ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0);
        ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
 
-       ath10k_dbg(ATH10K_DBG_BOOT,
+       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                   "boot ce dest ring id %d entries %d base_addr %p\n",
                   ce_id, nentries, dest_ring->base_addr_owner_space);
 
@@ -1064,7 +1023,9 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
  * initialized by software/firmware.
  */
 int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
-                       const struct ce_attr *attr)
+                       const struct ce_attr *attr,
+                       void (*send_cb)(struct ath10k_ce_pipe *),
+                       void (*recv_cb)(struct ath10k_ce_pipe *))
 {
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
        struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
@@ -1081,39 +1042,37 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
        BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC >
                     (CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
 
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return ret;
-
        spin_lock_bh(&ar_pci->ce_lock);
        ce_state->ar = ar;
        ce_state->id = ce_id;
        ce_state->ctrl_addr = ath10k_ce_base_address(ce_id);
        ce_state->attr_flags = attr->flags;
        ce_state->src_sz_max = attr->src_sz_max;
+       if (attr->src_nentries)
+               ce_state->send_cb = send_cb;
+       if (attr->dest_nentries)
+               ce_state->recv_cb = recv_cb;
        spin_unlock_bh(&ar_pci->ce_lock);
 
        if (attr->src_nentries) {
                ret = ath10k_ce_init_src_ring(ar, ce_id, attr);
                if (ret) {
-                       ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n",
+                       ath10k_err(ar, "Failed to initialize CE src ring for ID: %d (%d)\n",
                                   ce_id, ret);
-                       goto out;
+                       return ret;
                }
        }
 
        if (attr->dest_nentries) {
                ret = ath10k_ce_init_dest_ring(ar, ce_id, attr);
                if (ret) {
-                       ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n",
+                       ath10k_err(ar, "Failed to initialize CE dest ring for ID: %d (%d)\n",
                                   ce_id, ret);
-                       goto out;
+                       return ret;
                }
        }
 
-out:
-       ath10k_pci_sleep(ar);
-       return ret;
+       return 0;
 }
 
 static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id)
@@ -1137,16 +1096,8 @@ static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id)
 
 void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id)
 {
-       int ret;
-
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return;
-
        ath10k_ce_deinit_src_ring(ar, ce_id);
        ath10k_ce_deinit_dest_ring(ar, ce_id);
-
-       ath10k_pci_sleep(ar);
 }
 
 int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
@@ -1160,7 +1111,7 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
                ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr);
                if (IS_ERR(ce_state->src_ring)) {
                        ret = PTR_ERR(ce_state->src_ring);
-                       ath10k_err("failed to allocate copy engine source ring %d: %d\n",
+                       ath10k_err(ar, "failed to allocate copy engine source ring %d: %d\n",
                                   ce_id, ret);
                        ce_state->src_ring = NULL;
                        return ret;
@@ -1172,7 +1123,7 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
                                                                attr);
                if (IS_ERR(ce_state->dest_ring)) {
                        ret = PTR_ERR(ce_state->dest_ring);
-                       ath10k_err("failed to allocate copy engine destination ring %d: %d\n",
+                       ath10k_err(ar, "failed to allocate copy engine destination ring %d: %d\n",
                                   ce_id, ret);
                        ce_state->dest_ring = NULL;
                        return ret;