Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1283c617 authored by Kalle Valo's avatar Kalle Valo
Browse files
ath.git patches for 4.14. Major changes:

ath10k

* preparation for wcn3990 support
parents 6e9aae17 75e0dde2
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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) {
+164 −135
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
 */

#include "hif.h"
#include "pci.h"
#include "ce.h"
#include "debug.h"

@@ -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
@@ -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);
}

@@ -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);
}

@@ -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);
}

@@ -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);
}

@@ -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));
}
@@ -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));
}
@@ -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));
}
@@ -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);
}

@@ -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);
}

@@ -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);
}

@@ -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)));
}
@@ -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)));
}
@@ -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)));
}
@@ -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)));
}
@@ -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);
}

@@ -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));
}

@@ -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));
}

@@ -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);
}

@@ -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));
}

@@ -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);
}

/*
@@ -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
@@ -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;
}
@@ -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;
}
@@ -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);
}
@@ -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;
@@ -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)
@@ -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;
}
@@ -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;
}
@@ -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;

@@ -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;
@@ -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;
}
@@ -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;

@@ -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;
@@ -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;
}
@@ -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;
}
@@ -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);
@@ -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
@@ -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);
}

/*
@@ -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))
@@ -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);

@@ -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);

@@ -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;

	/*
@@ -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,
@@ -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);
}
+26 −4
Original line number Diff line number Diff line
@@ -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 */
@@ -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_ */
+5 −0
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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