Loading drivers/net/wireless/ath/ath10k/ahb.c +2 −1 Original line number Diff line number Diff line Loading @@ -787,8 +787,9 @@ static int ath10k_ahb_probe(struct platform_device *pdev) ar_pci->mem = ar_ahb->mem; ar_pci->mem_len = ar_ahb->mem_len; ar_pci->ar = ar; ar_pci->bus_ops = &ath10k_ahb_bus_ops; ar_pci->ce.bus_ops = &ath10k_ahb_bus_ops; ar_pci->targ_cpu_to_ce_addr = ath10k_ahb_qca4019_targ_cpu_to_ce_addr; ar->ce_priv = &ar_pci->ce; ret = ath10k_pci_setup_resource(ar); if (ret) { Loading drivers/net/wireless/ath/ath10k/ce.c +164 −135 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ */ #include "hif.h" #include "pci.h" #include "ce.h" #include "debug.h" Loading @@ -33,7 +32,7 @@ * Each ring consists of a number of descriptors which specify * an address, length, and meta-data. * * Typically, one side of the PCIe interconnect (Host or Target) * Typically, one side of the PCIe/AHB/SNOC interconnect (Host or Target) * controls one ring and the other side controls the other ring. * The source side chooses when to initiate a transfer and it * chooses what to send (buffer address, length). The destination Loading Loading @@ -73,18 +72,32 @@ ath10k_get_ring_byte(unsigned int offset, return ((offset & addr_map->mask) >> (addr_map->lsb)); } static inline u32 ath10k_ce_read32(struct ath10k *ar, u32 offset) { struct ath10k_ce *ce = ath10k_ce_priv(ar); return ce->bus_ops->read32(ar, offset); } static inline void ath10k_ce_write32(struct ath10k *ar, u32 offset, u32 value) { struct ath10k_ce *ce = ath10k_ce_priv(ar); ce->bus_ops->write32(ar, offset, value); } static inline void ath10k_ce_dest_ring_write_index_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int n) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->dst_wr_index_addr, n); } static inline u32 ath10k_ce_dest_ring_write_index_get(struct ath10k *ar, u32 ce_ctrl_addr) { return ath10k_pci_read32(ar, ce_ctrl_addr + return ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->dst_wr_index_addr); } Loading @@ -92,21 +105,21 @@ static inline void ath10k_ce_src_ring_write_index_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int n) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->sr_wr_index_addr, n); } static inline u32 ath10k_ce_src_ring_write_index_get(struct ath10k *ar, u32 ce_ctrl_addr) { return ath10k_pci_read32(ar, ce_ctrl_addr + return ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->sr_wr_index_addr); } static inline u32 ath10k_ce_src_ring_read_index_get(struct ath10k *ar, u32 ce_ctrl_addr) { return ath10k_pci_read32(ar, ce_ctrl_addr + return ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->current_srri_addr); } Loading @@ -114,7 +127,7 @@ static inline void ath10k_ce_src_ring_base_addr_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int addr) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->sr_base_addr, addr); } Loading @@ -122,7 +135,7 @@ static inline void ath10k_ce_src_ring_size_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int n) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->sr_size_addr, n); } Loading @@ -131,10 +144,11 @@ static inline void ath10k_ce_src_ring_dmax_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs; u32 ctrl1_addr = ath10k_pci_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_pci_write32(ar, ce_ctrl_addr + ctrl_regs->addr, u32 ctrl1_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_ce_write32(ar, ce_ctrl_addr + ctrl_regs->addr, (ctrl1_addr & ~(ctrl_regs->dmax->mask)) | ath10k_set_ring_byte(n, ctrl_regs->dmax)); } Loading @@ -144,9 +158,11 @@ static inline void ath10k_ce_src_ring_byte_swap_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs; u32 ctrl1_addr = ath10k_pci_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_pci_write32(ar, ce_ctrl_addr + ctrl_regs->addr, u32 ctrl1_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_ce_write32(ar, ce_ctrl_addr + ctrl_regs->addr, (ctrl1_addr & ~(ctrl_regs->src_ring->mask)) | ath10k_set_ring_byte(n, ctrl_regs->src_ring)); } Loading @@ -156,9 +172,11 @@ static inline void ath10k_ce_dest_ring_byte_swap_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs; u32 ctrl1_addr = ath10k_pci_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_pci_write32(ar, ce_ctrl_addr + ctrl_regs->addr, u32 ctrl1_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_ce_write32(ar, ce_ctrl_addr + ctrl_regs->addr, (ctrl1_addr & ~(ctrl_regs->dst_ring->mask)) | ath10k_set_ring_byte(n, ctrl_regs->dst_ring)); } Loading @@ -166,7 +184,7 @@ static inline void ath10k_ce_dest_ring_byte_swap_set(struct ath10k *ar, static inline u32 ath10k_ce_dest_ring_read_index_get(struct ath10k *ar, u32 ce_ctrl_addr) { return ath10k_pci_read32(ar, ce_ctrl_addr + return ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->current_drri_addr); } Loading @@ -174,7 +192,7 @@ static inline void ath10k_ce_dest_ring_base_addr_set(struct ath10k *ar, u32 ce_ctrl_addr, u32 addr) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->dr_base_addr, addr); } Loading @@ -182,7 +200,7 @@ static inline void ath10k_ce_dest_ring_size_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int n) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->dr_size_addr, n); } Loading @@ -191,9 +209,9 @@ static inline void ath10k_ce_src_ring_highmark_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_dst_src_wm_regs *srcr_wm = ar->hw_ce_regs->wm_srcr; u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + srcr_wm->addr); u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + srcr_wm->addr); ath10k_pci_write32(ar, ce_ctrl_addr + srcr_wm->addr, ath10k_ce_write32(ar, ce_ctrl_addr + srcr_wm->addr, (addr & ~(srcr_wm->wm_high->mask)) | (ath10k_set_ring_byte(n, srcr_wm->wm_high))); } Loading @@ -203,9 +221,9 @@ static inline void ath10k_ce_src_ring_lowmark_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_dst_src_wm_regs *srcr_wm = ar->hw_ce_regs->wm_srcr; u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + srcr_wm->addr); u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + srcr_wm->addr); ath10k_pci_write32(ar, ce_ctrl_addr + srcr_wm->addr, ath10k_ce_write32(ar, ce_ctrl_addr + srcr_wm->addr, (addr & ~(srcr_wm->wm_low->mask)) | (ath10k_set_ring_byte(n, srcr_wm->wm_low))); } Loading @@ -215,9 +233,9 @@ static inline void ath10k_ce_dest_ring_highmark_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_dst_src_wm_regs *dstr_wm = ar->hw_ce_regs->wm_dstr; u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + dstr_wm->addr); u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + dstr_wm->addr); ath10k_pci_write32(ar, ce_ctrl_addr + dstr_wm->addr, ath10k_ce_write32(ar, ce_ctrl_addr + dstr_wm->addr, (addr & ~(dstr_wm->wm_high->mask)) | (ath10k_set_ring_byte(n, dstr_wm->wm_high))); } Loading @@ -227,9 +245,9 @@ static inline void ath10k_ce_dest_ring_lowmark_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_dst_src_wm_regs *dstr_wm = ar->hw_ce_regs->wm_dstr; u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + dstr_wm->addr); u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + dstr_wm->addr); ath10k_pci_write32(ar, ce_ctrl_addr + dstr_wm->addr, ath10k_ce_write32(ar, ce_ctrl_addr + dstr_wm->addr, (addr & ~(dstr_wm->wm_low->mask)) | (ath10k_set_ring_byte(n, dstr_wm->wm_low))); } Loading @@ -238,10 +256,11 @@ static inline void ath10k_ce_copy_complete_inter_enable(struct ath10k *ar, u32 ce_ctrl_addr) { struct ath10k_hw_ce_host_ie *host_ie = ar->hw_ce_regs->host_ie; u32 host_ie_addr = ath10k_pci_read32(ar, ce_ctrl_addr + u32 host_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr); ath10k_pci_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, host_ie_addr | host_ie->copy_complete->mask); } Loading @@ -249,10 +268,11 @@ static inline void ath10k_ce_copy_complete_intr_disable(struct ath10k *ar, u32 ce_ctrl_addr) { struct ath10k_hw_ce_host_ie *host_ie = ar->hw_ce_regs->host_ie; u32 host_ie_addr = ath10k_pci_read32(ar, ce_ctrl_addr + u32 host_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr); ath10k_pci_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, host_ie_addr & ~(host_ie->copy_complete->mask)); } Loading @@ -260,10 +280,11 @@ static inline void ath10k_ce_watermark_intr_disable(struct ath10k *ar, u32 ce_ctrl_addr) { struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs; u32 host_ie_addr = ath10k_pci_read32(ar, ce_ctrl_addr + u32 host_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr); ath10k_pci_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, host_ie_addr & ~(wm_regs->wm_mask)); } Loading @@ -271,10 +292,12 @@ static inline void ath10k_ce_error_intr_enable(struct ath10k *ar, u32 ce_ctrl_addr) { struct ath10k_hw_ce_misc_regs *misc_regs = ar->hw_ce_regs->misc_regs; u32 misc_ie_addr = ath10k_pci_read32(ar, ce_ctrl_addr + u32 misc_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr); ath10k_pci_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr, ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr, misc_ie_addr | misc_regs->err_mask); } Loading @@ -282,10 +305,12 @@ static inline void ath10k_ce_error_intr_disable(struct ath10k *ar, u32 ce_ctrl_addr) { struct ath10k_hw_ce_misc_regs *misc_regs = ar->hw_ce_regs->misc_regs; u32 misc_ie_addr = ath10k_pci_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr); ath10k_pci_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr, u32 misc_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr); ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr, misc_ie_addr & ~(misc_regs->err_mask)); } Loading @@ -295,7 +320,7 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar, { struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs; ath10k_pci_write32(ar, ce_ctrl_addr + wm_regs->addr, mask); ath10k_ce_write32(ar, ce_ctrl_addr + wm_regs->addr, mask); } /* Loading Loading @@ -362,11 +387,11 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe) { struct ath10k *ar = pipe->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_ring *src_ring = pipe->src_ring; u32 ctrl_addr = pipe->ctrl_addr; lockdep_assert_held(&ar_pci->ce_lock); lockdep_assert_held(&ce->ce_lock); /* * This function must be called only if there is an incomplete Loading Loading @@ -394,13 +419,13 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, unsigned int flags) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); int ret; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); ret = ath10k_ce_send_nolock(ce_state, per_transfer_context, buffer, nbytes, transfer_id, flags); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading @@ -408,14 +433,14 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe) { struct ath10k *ar = pipe->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); int delta; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); delta = CE_RING_DELTA(pipe->src_ring->nentries_mask, pipe->src_ring->write_index, pipe->src_ring->sw_index - 1); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return delta; } Loading @@ -423,13 +448,13 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe) int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe) { struct ath10k *ar = pipe->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_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; lockdep_assert_held(&ar_pci->ce_lock); lockdep_assert_held(&ce->ce_lock); return CE_RING_DELTA(nentries_mask, write_index, sw_index - 1); } Loading @@ -437,7 +462,7 @@ int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe) 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 *ce = ath10k_ce_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; Loading @@ -446,7 +471,7 @@ int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr) struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index); u32 ctrl_addr = pipe->ctrl_addr; lockdep_assert_held(&ar_pci->ce_lock); lockdep_assert_held(&ce->ce_lock); if ((pipe->id != 5) && CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) == 0) Loading Loading @@ -486,12 +511,12 @@ void ath10k_ce_rx_update_write_idx(struct ath10k_ce_pipe *pipe, u32 nentries) 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 *ce = ath10k_ce_priv(ar); int ret; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); ret = __ath10k_ce_rx_post_buf(pipe, ctx, paddr); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading Loading @@ -554,14 +579,14 @@ int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state, unsigned int *nbytesp) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); int ret; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); ret = ath10k_ce_completed_recv_next_nolock(ce_state, per_transfer_contextp, nbytesp); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading @@ -576,7 +601,7 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, unsigned int write_index; int ret; struct ath10k *ar; struct ath10k_pci *ar_pci; struct ath10k_ce *ce; dest_ring = ce_state->dest_ring; Loading @@ -584,9 +609,9 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, return -EIO; ar = ce_state->ar; ar_pci = ath10k_pci_priv(ar); ce = ath10k_ce_priv(ar); spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); nentries_mask = dest_ring->nentries_mask; sw_index = dest_ring->sw_index; Loading Loading @@ -614,7 +639,7 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, ret = -EIO; } spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading Loading @@ -686,7 +711,7 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, unsigned int write_index; int ret; struct ath10k *ar; struct ath10k_pci *ar_pci; struct ath10k_ce *ce; src_ring = ce_state->src_ring; Loading @@ -694,9 +719,9 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, return -EIO; ar = ce_state->ar; ar_pci = ath10k_pci_priv(ar); ce = ath10k_ce_priv(ar); spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); nentries_mask = src_ring->nentries_mask; sw_index = src_ring->sw_index; Loading Loading @@ -727,7 +752,7 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, ret = -EIO; } spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading @@ -736,13 +761,13 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, void **per_transfer_contextp) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); int ret; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); ret = ath10k_ce_completed_send_next_nolock(ce_state, per_transfer_contextp); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading @@ -755,17 +780,18 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, */ 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]; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id]; struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs; u32 ctrl_addr = ce_state->ctrl_addr; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); /* Clear the copy-complete interrupts that will be handled here. */ ath10k_ce_engine_int_status_clear(ar, ctrl_addr, wm_regs->cc_mask); ath10k_ce_engine_int_status_clear(ar, ctrl_addr, wm_regs->cc_mask); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); if (ce_state->recv_cb) ce_state->recv_cb(ce_state); Loading @@ -773,7 +799,7 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) if (ce_state->send_cb) ce_state->send_cb(ce_state); spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); /* * Misc CE interrupts are not being handled, but still need Loading @@ -781,7 +807,7 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) */ ath10k_ce_engine_int_status_clear(ar, ctrl_addr, wm_regs->wm_mask); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); } /* Loading @@ -795,7 +821,7 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar) int ce_id; u32 intr_summary; intr_summary = CE_INTERRUPT_SUMMARY(ar); intr_summary = ath10k_ce_interrupt_summary(ar); for (ce_id = 0; intr_summary && (ce_id < CE_COUNT); ce_id++) { if (intr_summary & (1 << ce_id)) Loading Loading @@ -847,22 +873,25 @@ int ath10k_ce_disable_interrupts(struct ath10k *ar) void ath10k_ce_enable_interrupts(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); int ce_id; struct ath10k_ce_pipe *ce_state; /* 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]); for (ce_id = 0; ce_id < CE_COUNT - 1; ce_id++) { ce_state = &ce->ce_states[ce_id]; ath10k_ce_per_engine_handler_adjust(ce_state); } } static int ath10k_ce_init_src_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id]; struct ath10k_ce_ring *src_ring = ce_state->src_ring; u32 nentries, ctrl_addr = ath10k_ce_base_address(ar, ce_id); Loading Loading @@ -898,8 +927,8 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id]; struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; u32 nentries, ctrl_addr = ath10k_ce_base_address(ar, ce_id); Loading Loading @@ -1081,8 +1110,8 @@ void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id) int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id]; int ret; /* Loading Loading @@ -1138,8 +1167,8 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id]; if (ce_state->src_ring) { dma_free_coherent(ar->dev, Loading Loading @@ -1168,38 +1197,38 @@ void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id) void ath10k_ce_dump_registers(struct ath10k *ar, struct ath10k_fw_crash_data *crash_data) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_crash_data ce; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_crash_data ce_data; u32 addr, id; lockdep_assert_held(&ar->data_lock); ath10k_err(ar, "Copy Engine register dump:\n"); spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); for (id = 0; id < CE_COUNT; id++) { addr = ath10k_ce_base_address(ar, id); ce.base_addr = cpu_to_le32(addr); ce_data.base_addr = cpu_to_le32(addr); ce.src_wr_idx = ce_data.src_wr_idx = cpu_to_le32(ath10k_ce_src_ring_write_index_get(ar, addr)); ce.src_r_idx = ce_data.src_r_idx = cpu_to_le32(ath10k_ce_src_ring_read_index_get(ar, addr)); ce.dst_wr_idx = ce_data.dst_wr_idx = cpu_to_le32(ath10k_ce_dest_ring_write_index_get(ar, addr)); ce.dst_r_idx = ce_data.dst_r_idx = cpu_to_le32(ath10k_ce_dest_ring_read_index_get(ar, addr)); if (crash_data) crash_data->ce_crash_data[id] = ce; crash_data->ce_crash_data[id] = ce_data; ath10k_err(ar, "[%02d]: 0x%08x %3u %3u %3u %3u", id, le32_to_cpu(ce.base_addr), le32_to_cpu(ce.src_wr_idx), le32_to_cpu(ce.src_r_idx), le32_to_cpu(ce.dst_wr_idx), le32_to_cpu(ce.dst_r_idx)); le32_to_cpu(ce_data.base_addr), le32_to_cpu(ce_data.src_wr_idx), le32_to_cpu(ce_data.src_r_idx), le32_to_cpu(ce_data.dst_wr_idx), le32_to_cpu(ce_data.dst_r_idx)); } spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); } drivers/net/wireless/ath/ath10k/ce.h +26 −4 Original line number Diff line number Diff line Loading @@ -122,6 +122,24 @@ struct ath10k_ce_pipe { /* Copy Engine settable attributes */ struct ce_attr; struct ath10k_bus_ops { u32 (*read32)(struct ath10k *ar, u32 offset); void (*write32)(struct ath10k *ar, u32 offset, u32 value); int (*get_num_banks)(struct ath10k *ar); }; static inline struct ath10k_ce *ath10k_ce_priv(struct ath10k *ar) { return (struct ath10k_ce *)ar->ce_priv; } struct ath10k_ce { /* protects CE info */ spinlock_t ce_lock; const struct ath10k_bus_ops *bus_ops; struct ath10k_ce_pipe ce_states[CE_COUNT_MAX]; }; /*==================Send====================*/ /* ath10k_ce_send flags */ Loading Loading @@ -291,9 +309,13 @@ static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id) CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB) #define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 #define CE_INTERRUPT_SUMMARY(ar) \ CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET( \ ath10k_pci_read32((ar), CE_WRAPPER_BASE_ADDRESS + \ CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS)) static inline u32 ath10k_ce_interrupt_summary(struct ath10k *ar) { struct ath10k_ce *ce = ath10k_ce_priv(ar); return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET( ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS + CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS)); } #endif /* _CE_H_ */ drivers/net/wireless/ath/ath10k/core.c +5 −0 Original line number Diff line number Diff line Loading @@ -2516,6 +2516,11 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, ar->hw_ce_regs = &qcax_ce_regs; ar->hw_values = &qca4019_values; break; case ATH10K_HW_WCN3990: ar->regs = &wcn3990_regs; ar->hw_ce_regs = &wcn3990_ce_regs; ar->hw_values = &wcn3990_values; break; default: ath10k_err(ar, "unsupported core hardware revision %d\n", hw_rev); Loading drivers/net/wireless/ath/ath10k/core.h +2 −0 Original line number Diff line number Diff line Loading @@ -993,6 +993,8 @@ struct ath10k { u32 reg_ack_cts_timeout_orig; } fw_coverage; void *ce_priv; /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); }; Loading Loading
drivers/net/wireless/ath/ath10k/ahb.c +2 −1 Original line number Diff line number Diff line Loading @@ -787,8 +787,9 @@ static int ath10k_ahb_probe(struct platform_device *pdev) ar_pci->mem = ar_ahb->mem; ar_pci->mem_len = ar_ahb->mem_len; ar_pci->ar = ar; ar_pci->bus_ops = &ath10k_ahb_bus_ops; ar_pci->ce.bus_ops = &ath10k_ahb_bus_ops; ar_pci->targ_cpu_to_ce_addr = ath10k_ahb_qca4019_targ_cpu_to_ce_addr; ar->ce_priv = &ar_pci->ce; ret = ath10k_pci_setup_resource(ar); if (ret) { Loading
drivers/net/wireless/ath/ath10k/ce.c +164 −135 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ */ #include "hif.h" #include "pci.h" #include "ce.h" #include "debug.h" Loading @@ -33,7 +32,7 @@ * Each ring consists of a number of descriptors which specify * an address, length, and meta-data. * * Typically, one side of the PCIe interconnect (Host or Target) * Typically, one side of the PCIe/AHB/SNOC interconnect (Host or Target) * controls one ring and the other side controls the other ring. * The source side chooses when to initiate a transfer and it * chooses what to send (buffer address, length). The destination Loading Loading @@ -73,18 +72,32 @@ ath10k_get_ring_byte(unsigned int offset, return ((offset & addr_map->mask) >> (addr_map->lsb)); } static inline u32 ath10k_ce_read32(struct ath10k *ar, u32 offset) { struct ath10k_ce *ce = ath10k_ce_priv(ar); return ce->bus_ops->read32(ar, offset); } static inline void ath10k_ce_write32(struct ath10k *ar, u32 offset, u32 value) { struct ath10k_ce *ce = ath10k_ce_priv(ar); ce->bus_ops->write32(ar, offset, value); } static inline void ath10k_ce_dest_ring_write_index_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int n) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->dst_wr_index_addr, n); } static inline u32 ath10k_ce_dest_ring_write_index_get(struct ath10k *ar, u32 ce_ctrl_addr) { return ath10k_pci_read32(ar, ce_ctrl_addr + return ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->dst_wr_index_addr); } Loading @@ -92,21 +105,21 @@ static inline void ath10k_ce_src_ring_write_index_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int n) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->sr_wr_index_addr, n); } static inline u32 ath10k_ce_src_ring_write_index_get(struct ath10k *ar, u32 ce_ctrl_addr) { return ath10k_pci_read32(ar, ce_ctrl_addr + return ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->sr_wr_index_addr); } static inline u32 ath10k_ce_src_ring_read_index_get(struct ath10k *ar, u32 ce_ctrl_addr) { return ath10k_pci_read32(ar, ce_ctrl_addr + return ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->current_srri_addr); } Loading @@ -114,7 +127,7 @@ static inline void ath10k_ce_src_ring_base_addr_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int addr) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->sr_base_addr, addr); } Loading @@ -122,7 +135,7 @@ static inline void ath10k_ce_src_ring_size_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int n) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->sr_size_addr, n); } Loading @@ -131,10 +144,11 @@ static inline void ath10k_ce_src_ring_dmax_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs; u32 ctrl1_addr = ath10k_pci_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_pci_write32(ar, ce_ctrl_addr + ctrl_regs->addr, u32 ctrl1_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_ce_write32(ar, ce_ctrl_addr + ctrl_regs->addr, (ctrl1_addr & ~(ctrl_regs->dmax->mask)) | ath10k_set_ring_byte(n, ctrl_regs->dmax)); } Loading @@ -144,9 +158,11 @@ static inline void ath10k_ce_src_ring_byte_swap_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs; u32 ctrl1_addr = ath10k_pci_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_pci_write32(ar, ce_ctrl_addr + ctrl_regs->addr, u32 ctrl1_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_ce_write32(ar, ce_ctrl_addr + ctrl_regs->addr, (ctrl1_addr & ~(ctrl_regs->src_ring->mask)) | ath10k_set_ring_byte(n, ctrl_regs->src_ring)); } Loading @@ -156,9 +172,11 @@ static inline void ath10k_ce_dest_ring_byte_swap_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs; u32 ctrl1_addr = ath10k_pci_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_pci_write32(ar, ce_ctrl_addr + ctrl_regs->addr, u32 ctrl1_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ctrl_regs->addr); ath10k_ce_write32(ar, ce_ctrl_addr + ctrl_regs->addr, (ctrl1_addr & ~(ctrl_regs->dst_ring->mask)) | ath10k_set_ring_byte(n, ctrl_regs->dst_ring)); } Loading @@ -166,7 +184,7 @@ static inline void ath10k_ce_dest_ring_byte_swap_set(struct ath10k *ar, static inline u32 ath10k_ce_dest_ring_read_index_get(struct ath10k *ar, u32 ce_ctrl_addr) { return ath10k_pci_read32(ar, ce_ctrl_addr + return ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->current_drri_addr); } Loading @@ -174,7 +192,7 @@ static inline void ath10k_ce_dest_ring_base_addr_set(struct ath10k *ar, u32 ce_ctrl_addr, u32 addr) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->dr_base_addr, addr); } Loading @@ -182,7 +200,7 @@ static inline void ath10k_ce_dest_ring_size_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int n) { ath10k_pci_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->dr_size_addr, n); } Loading @@ -191,9 +209,9 @@ static inline void ath10k_ce_src_ring_highmark_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_dst_src_wm_regs *srcr_wm = ar->hw_ce_regs->wm_srcr; u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + srcr_wm->addr); u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + srcr_wm->addr); ath10k_pci_write32(ar, ce_ctrl_addr + srcr_wm->addr, ath10k_ce_write32(ar, ce_ctrl_addr + srcr_wm->addr, (addr & ~(srcr_wm->wm_high->mask)) | (ath10k_set_ring_byte(n, srcr_wm->wm_high))); } Loading @@ -203,9 +221,9 @@ static inline void ath10k_ce_src_ring_lowmark_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_dst_src_wm_regs *srcr_wm = ar->hw_ce_regs->wm_srcr; u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + srcr_wm->addr); u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + srcr_wm->addr); ath10k_pci_write32(ar, ce_ctrl_addr + srcr_wm->addr, ath10k_ce_write32(ar, ce_ctrl_addr + srcr_wm->addr, (addr & ~(srcr_wm->wm_low->mask)) | (ath10k_set_ring_byte(n, srcr_wm->wm_low))); } Loading @@ -215,9 +233,9 @@ static inline void ath10k_ce_dest_ring_highmark_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_dst_src_wm_regs *dstr_wm = ar->hw_ce_regs->wm_dstr; u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + dstr_wm->addr); u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + dstr_wm->addr); ath10k_pci_write32(ar, ce_ctrl_addr + dstr_wm->addr, ath10k_ce_write32(ar, ce_ctrl_addr + dstr_wm->addr, (addr & ~(dstr_wm->wm_high->mask)) | (ath10k_set_ring_byte(n, dstr_wm->wm_high))); } Loading @@ -227,9 +245,9 @@ static inline void ath10k_ce_dest_ring_lowmark_set(struct ath10k *ar, unsigned int n) { struct ath10k_hw_ce_dst_src_wm_regs *dstr_wm = ar->hw_ce_regs->wm_dstr; u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + dstr_wm->addr); u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + dstr_wm->addr); ath10k_pci_write32(ar, ce_ctrl_addr + dstr_wm->addr, ath10k_ce_write32(ar, ce_ctrl_addr + dstr_wm->addr, (addr & ~(dstr_wm->wm_low->mask)) | (ath10k_set_ring_byte(n, dstr_wm->wm_low))); } Loading @@ -238,10 +256,11 @@ static inline void ath10k_ce_copy_complete_inter_enable(struct ath10k *ar, u32 ce_ctrl_addr) { struct ath10k_hw_ce_host_ie *host_ie = ar->hw_ce_regs->host_ie; u32 host_ie_addr = ath10k_pci_read32(ar, ce_ctrl_addr + u32 host_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr); ath10k_pci_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, host_ie_addr | host_ie->copy_complete->mask); } Loading @@ -249,10 +268,11 @@ static inline void ath10k_ce_copy_complete_intr_disable(struct ath10k *ar, u32 ce_ctrl_addr) { struct ath10k_hw_ce_host_ie *host_ie = ar->hw_ce_regs->host_ie; u32 host_ie_addr = ath10k_pci_read32(ar, ce_ctrl_addr + u32 host_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr); ath10k_pci_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, host_ie_addr & ~(host_ie->copy_complete->mask)); } Loading @@ -260,10 +280,11 @@ static inline void ath10k_ce_watermark_intr_disable(struct ath10k *ar, u32 ce_ctrl_addr) { struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs; u32 host_ie_addr = ath10k_pci_read32(ar, ce_ctrl_addr + u32 host_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr); ath10k_pci_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->host_ie_addr, host_ie_addr & ~(wm_regs->wm_mask)); } Loading @@ -271,10 +292,12 @@ static inline void ath10k_ce_error_intr_enable(struct ath10k *ar, u32 ce_ctrl_addr) { struct ath10k_hw_ce_misc_regs *misc_regs = ar->hw_ce_regs->misc_regs; u32 misc_ie_addr = ath10k_pci_read32(ar, ce_ctrl_addr + u32 misc_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr); ath10k_pci_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr, ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr, misc_ie_addr | misc_regs->err_mask); } Loading @@ -282,10 +305,12 @@ static inline void ath10k_ce_error_intr_disable(struct ath10k *ar, u32 ce_ctrl_addr) { struct ath10k_hw_ce_misc_regs *misc_regs = ar->hw_ce_regs->misc_regs; u32 misc_ie_addr = ath10k_pci_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr); ath10k_pci_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr, u32 misc_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr); ath10k_ce_write32(ar, ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr, misc_ie_addr & ~(misc_regs->err_mask)); } Loading @@ -295,7 +320,7 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar, { struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs; ath10k_pci_write32(ar, ce_ctrl_addr + wm_regs->addr, mask); ath10k_ce_write32(ar, ce_ctrl_addr + wm_regs->addr, mask); } /* Loading Loading @@ -362,11 +387,11 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe) { struct ath10k *ar = pipe->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_ring *src_ring = pipe->src_ring; u32 ctrl_addr = pipe->ctrl_addr; lockdep_assert_held(&ar_pci->ce_lock); lockdep_assert_held(&ce->ce_lock); /* * This function must be called only if there is an incomplete Loading Loading @@ -394,13 +419,13 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, unsigned int flags) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); int ret; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); ret = ath10k_ce_send_nolock(ce_state, per_transfer_context, buffer, nbytes, transfer_id, flags); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading @@ -408,14 +433,14 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe) { struct ath10k *ar = pipe->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); int delta; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); delta = CE_RING_DELTA(pipe->src_ring->nentries_mask, pipe->src_ring->write_index, pipe->src_ring->sw_index - 1); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return delta; } Loading @@ -423,13 +448,13 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe) int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe) { struct ath10k *ar = pipe->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_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; lockdep_assert_held(&ar_pci->ce_lock); lockdep_assert_held(&ce->ce_lock); return CE_RING_DELTA(nentries_mask, write_index, sw_index - 1); } Loading @@ -437,7 +462,7 @@ int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe) 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 *ce = ath10k_ce_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; Loading @@ -446,7 +471,7 @@ int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr) struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index); u32 ctrl_addr = pipe->ctrl_addr; lockdep_assert_held(&ar_pci->ce_lock); lockdep_assert_held(&ce->ce_lock); if ((pipe->id != 5) && CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) == 0) Loading Loading @@ -486,12 +511,12 @@ void ath10k_ce_rx_update_write_idx(struct ath10k_ce_pipe *pipe, u32 nentries) 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 *ce = ath10k_ce_priv(ar); int ret; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); ret = __ath10k_ce_rx_post_buf(pipe, ctx, paddr); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading Loading @@ -554,14 +579,14 @@ int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state, unsigned int *nbytesp) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); int ret; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); ret = ath10k_ce_completed_recv_next_nolock(ce_state, per_transfer_contextp, nbytesp); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading @@ -576,7 +601,7 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, unsigned int write_index; int ret; struct ath10k *ar; struct ath10k_pci *ar_pci; struct ath10k_ce *ce; dest_ring = ce_state->dest_ring; Loading @@ -584,9 +609,9 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, return -EIO; ar = ce_state->ar; ar_pci = ath10k_pci_priv(ar); ce = ath10k_ce_priv(ar); spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); nentries_mask = dest_ring->nentries_mask; sw_index = dest_ring->sw_index; Loading Loading @@ -614,7 +639,7 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, ret = -EIO; } spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading Loading @@ -686,7 +711,7 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, unsigned int write_index; int ret; struct ath10k *ar; struct ath10k_pci *ar_pci; struct ath10k_ce *ce; src_ring = ce_state->src_ring; Loading @@ -694,9 +719,9 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, return -EIO; ar = ce_state->ar; ar_pci = ath10k_pci_priv(ar); ce = ath10k_ce_priv(ar); spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); nentries_mask = src_ring->nentries_mask; sw_index = src_ring->sw_index; Loading Loading @@ -727,7 +752,7 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, ret = -EIO; } spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading @@ -736,13 +761,13 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, void **per_transfer_contextp) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); int ret; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); ret = ath10k_ce_completed_send_next_nolock(ce_state, per_transfer_contextp); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); return ret; } Loading @@ -755,17 +780,18 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, */ 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]; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id]; struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs; u32 ctrl_addr = ce_state->ctrl_addr; spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); /* Clear the copy-complete interrupts that will be handled here. */ ath10k_ce_engine_int_status_clear(ar, ctrl_addr, wm_regs->cc_mask); ath10k_ce_engine_int_status_clear(ar, ctrl_addr, wm_regs->cc_mask); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); if (ce_state->recv_cb) ce_state->recv_cb(ce_state); Loading @@ -773,7 +799,7 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) if (ce_state->send_cb) ce_state->send_cb(ce_state); spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); /* * Misc CE interrupts are not being handled, but still need Loading @@ -781,7 +807,7 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) */ ath10k_ce_engine_int_status_clear(ar, ctrl_addr, wm_regs->wm_mask); spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); } /* Loading @@ -795,7 +821,7 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar) int ce_id; u32 intr_summary; intr_summary = CE_INTERRUPT_SUMMARY(ar); intr_summary = ath10k_ce_interrupt_summary(ar); for (ce_id = 0; intr_summary && (ce_id < CE_COUNT); ce_id++) { if (intr_summary & (1 << ce_id)) Loading Loading @@ -847,22 +873,25 @@ int ath10k_ce_disable_interrupts(struct ath10k *ar) void ath10k_ce_enable_interrupts(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce *ce = ath10k_ce_priv(ar); int ce_id; struct ath10k_ce_pipe *ce_state; /* 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]); for (ce_id = 0; ce_id < CE_COUNT - 1; ce_id++) { ce_state = &ce->ce_states[ce_id]; ath10k_ce_per_engine_handler_adjust(ce_state); } } static int ath10k_ce_init_src_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id]; struct ath10k_ce_ring *src_ring = ce_state->src_ring; u32 nentries, ctrl_addr = ath10k_ce_base_address(ar, ce_id); Loading Loading @@ -898,8 +927,8 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id]; struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; u32 nentries, ctrl_addr = ath10k_ce_base_address(ar, ce_id); Loading Loading @@ -1081,8 +1110,8 @@ void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id) int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id]; int ret; /* Loading Loading @@ -1138,8 +1167,8 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id]; if (ce_state->src_ring) { dma_free_coherent(ar->dev, Loading Loading @@ -1168,38 +1197,38 @@ void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id) void ath10k_ce_dump_registers(struct ath10k *ar, struct ath10k_fw_crash_data *crash_data) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_crash_data ce; struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_crash_data ce_data; u32 addr, id; lockdep_assert_held(&ar->data_lock); ath10k_err(ar, "Copy Engine register dump:\n"); spin_lock_bh(&ar_pci->ce_lock); spin_lock_bh(&ce->ce_lock); for (id = 0; id < CE_COUNT; id++) { addr = ath10k_ce_base_address(ar, id); ce.base_addr = cpu_to_le32(addr); ce_data.base_addr = cpu_to_le32(addr); ce.src_wr_idx = ce_data.src_wr_idx = cpu_to_le32(ath10k_ce_src_ring_write_index_get(ar, addr)); ce.src_r_idx = ce_data.src_r_idx = cpu_to_le32(ath10k_ce_src_ring_read_index_get(ar, addr)); ce.dst_wr_idx = ce_data.dst_wr_idx = cpu_to_le32(ath10k_ce_dest_ring_write_index_get(ar, addr)); ce.dst_r_idx = ce_data.dst_r_idx = cpu_to_le32(ath10k_ce_dest_ring_read_index_get(ar, addr)); if (crash_data) crash_data->ce_crash_data[id] = ce; crash_data->ce_crash_data[id] = ce_data; ath10k_err(ar, "[%02d]: 0x%08x %3u %3u %3u %3u", id, le32_to_cpu(ce.base_addr), le32_to_cpu(ce.src_wr_idx), le32_to_cpu(ce.src_r_idx), le32_to_cpu(ce.dst_wr_idx), le32_to_cpu(ce.dst_r_idx)); le32_to_cpu(ce_data.base_addr), le32_to_cpu(ce_data.src_wr_idx), le32_to_cpu(ce_data.src_r_idx), le32_to_cpu(ce_data.dst_wr_idx), le32_to_cpu(ce_data.dst_r_idx)); } spin_unlock_bh(&ar_pci->ce_lock); spin_unlock_bh(&ce->ce_lock); }
drivers/net/wireless/ath/ath10k/ce.h +26 −4 Original line number Diff line number Diff line Loading @@ -122,6 +122,24 @@ struct ath10k_ce_pipe { /* Copy Engine settable attributes */ struct ce_attr; struct ath10k_bus_ops { u32 (*read32)(struct ath10k *ar, u32 offset); void (*write32)(struct ath10k *ar, u32 offset, u32 value); int (*get_num_banks)(struct ath10k *ar); }; static inline struct ath10k_ce *ath10k_ce_priv(struct ath10k *ar) { return (struct ath10k_ce *)ar->ce_priv; } struct ath10k_ce { /* protects CE info */ spinlock_t ce_lock; const struct ath10k_bus_ops *bus_ops; struct ath10k_ce_pipe ce_states[CE_COUNT_MAX]; }; /*==================Send====================*/ /* ath10k_ce_send flags */ Loading Loading @@ -291,9 +309,13 @@ static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id) CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB) #define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 #define CE_INTERRUPT_SUMMARY(ar) \ CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET( \ ath10k_pci_read32((ar), CE_WRAPPER_BASE_ADDRESS + \ CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS)) static inline u32 ath10k_ce_interrupt_summary(struct ath10k *ar) { struct ath10k_ce *ce = ath10k_ce_priv(ar); return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET( ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS + CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS)); } #endif /* _CE_H_ */
drivers/net/wireless/ath/ath10k/core.c +5 −0 Original line number Diff line number Diff line Loading @@ -2516,6 +2516,11 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, ar->hw_ce_regs = &qcax_ce_regs; ar->hw_values = &qca4019_values; break; case ATH10K_HW_WCN3990: ar->regs = &wcn3990_regs; ar->hw_ce_regs = &wcn3990_ce_regs; ar->hw_values = &wcn3990_values; break; default: ath10k_err(ar, "unsupported core hardware revision %d\n", hw_rev); Loading
drivers/net/wireless/ath/ath10k/core.h +2 −0 Original line number Diff line number Diff line Loading @@ -993,6 +993,8 @@ struct ath10k { u32 reg_ack_cts_timeout_orig; } fw_coverage; void *ce_priv; /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); }; Loading