Commit 5b9030ce authored by Rakesh Pillai's avatar Rakesh Pillai Committed by Kalle Valo

ath10k: Set DMA address mask to 35 bit for WCN3990

WCN3990 is a 37-bit target but can address memory range
only upto 35 bits. The 36th bit is used to control the
smmu/iommu translation and the 37th bit is used by the
internal bus masters to access the wifi subsystem internal
SRAM. With the DMA mask set to 37i-bit, the host driver
can get 37-bit dma address, which leads to incorrect
address access in the target.

Hence the host driver can used addresses upto 35-bit
for WCN3990. Fix the dma mask for wcn3990 to 35-bit,
instead of 37-bit.

Tested HW: WCN3990
Tested FW: WLAN.HL.2.0-01188-QCAHLSWMTPLZ-1
Tested-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: default avatarRakesh Pillai <pillair@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent fc6a6521
...@@ -228,11 +228,31 @@ ath10k_ce_shadow_dest_ring_write_index_set(struct ath10k *ar, ...@@ -228,11 +228,31 @@ ath10k_ce_shadow_dest_ring_write_index_set(struct ath10k *ar,
} }
static inline void ath10k_ce_src_ring_base_addr_set(struct ath10k *ar, static inline void ath10k_ce_src_ring_base_addr_set(struct ath10k *ar,
u32 ce_ctrl_addr, u32 ce_id,
unsigned int addr) u64 addr)
{
struct ath10k_ce *ce = ath10k_ce_priv(ar);
struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id];
u32 ce_ctrl_addr = ath10k_ce_base_address(ar, ce_id);
u32 addr_lo = lower_32_bits(addr);
ath10k_ce_write32(ar, ce_ctrl_addr +
ar->hw_ce_regs->sr_base_addr_lo, addr_lo);
if (ce_state->ops->ce_set_src_ring_base_addr_hi) {
ce_state->ops->ce_set_src_ring_base_addr_hi(ar, ce_ctrl_addr,
addr);
}
}
static void ath10k_ce_set_src_ring_base_addr_hi(struct ath10k *ar,
u32 ce_ctrl_addr,
u64 addr)
{ {
u32 addr_hi = upper_32_bits(addr) & CE_DESC_ADDR_HI_MASK;
ath10k_ce_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr +
ar->hw_ce_regs->sr_base_addr, addr); ar->hw_ce_regs->sr_base_addr_hi, addr_hi);
} }
static inline void ath10k_ce_src_ring_size_set(struct ath10k *ar, static inline void ath10k_ce_src_ring_size_set(struct ath10k *ar,
...@@ -313,11 +333,36 @@ static inline u32 ath10k_ce_dest_ring_read_index_get(struct ath10k *ar, ...@@ -313,11 +333,36 @@ static inline u32 ath10k_ce_dest_ring_read_index_get(struct ath10k *ar,
} }
static inline void ath10k_ce_dest_ring_base_addr_set(struct ath10k *ar, static inline void ath10k_ce_dest_ring_base_addr_set(struct ath10k *ar,
u32 ce_ctrl_addr, u32 ce_id,
u32 addr) u64 addr)
{ {
struct ath10k_ce *ce = ath10k_ce_priv(ar);
struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id];
u32 ce_ctrl_addr = ath10k_ce_base_address(ar, ce_id);
u32 addr_lo = lower_32_bits(addr);
ath10k_ce_write32(ar, ce_ctrl_addr +
ar->hw_ce_regs->dr_base_addr_lo, addr_lo);
if (ce_state->ops->ce_set_dest_ring_base_addr_hi) {
ce_state->ops->ce_set_dest_ring_base_addr_hi(ar, ce_ctrl_addr,
addr);
}
}
static void ath10k_ce_set_dest_ring_base_addr_hi(struct ath10k *ar,
u32 ce_ctrl_addr,
u64 addr)
{
u32 addr_hi = upper_32_bits(addr) & CE_DESC_ADDR_HI_MASK;
u32 reg_value;
reg_value = ath10k_ce_read32(ar, ce_ctrl_addr +
ar->hw_ce_regs->dr_base_addr_hi);
reg_value &= ~CE_DESC_ADDR_HI_MASK;
reg_value |= addr_hi;
ath10k_ce_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr +
ar->hw_ce_regs->dr_base_addr, addr); ar->hw_ce_regs->dr_base_addr_hi, reg_value);
} }
static inline void ath10k_ce_dest_ring_size_set(struct ath10k *ar, static inline void ath10k_ce_dest_ring_size_set(struct ath10k *ar,
...@@ -563,7 +608,7 @@ static int _ath10k_ce_send_nolock_64(struct ath10k_ce_pipe *ce_state, ...@@ -563,7 +608,7 @@ static int _ath10k_ce_send_nolock_64(struct ath10k_ce_pipe *ce_state,
addr = (__le32 *)&sdesc.addr; addr = (__le32 *)&sdesc.addr;
flags |= upper_32_bits(buffer) & CE_DESC_FLAGS_GET_MASK; flags |= upper_32_bits(buffer) & CE_DESC_ADDR_HI_MASK;
addr[0] = __cpu_to_le32(buffer); addr[0] = __cpu_to_le32(buffer);
addr[1] = __cpu_to_le32(flags); addr[1] = __cpu_to_le32(flags);
if (flags & CE_SEND_FLAG_GATHER) if (flags & CE_SEND_FLAG_GATHER)
...@@ -731,7 +776,7 @@ static int __ath10k_ce_rx_post_buf_64(struct ath10k_ce_pipe *pipe, ...@@ -731,7 +776,7 @@ static int __ath10k_ce_rx_post_buf_64(struct ath10k_ce_pipe *pipe,
return -ENOSPC; return -ENOSPC;
desc->addr = __cpu_to_le64(paddr); desc->addr = __cpu_to_le64(paddr);
desc->addr &= __cpu_to_le64(CE_DESC_37BIT_ADDR_MASK); desc->addr &= __cpu_to_le64(CE_DESC_ADDR_MASK);
desc->nbytes = 0; desc->nbytes = 0;
...@@ -1346,7 +1391,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, ...@@ -1346,7 +1391,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
ath10k_ce_src_ring_write_index_get(ar, ctrl_addr); ath10k_ce_src_ring_write_index_get(ar, ctrl_addr);
src_ring->write_index &= src_ring->nentries_mask; src_ring->write_index &= src_ring->nentries_mask;
ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, ath10k_ce_src_ring_base_addr_set(ar, ce_id,
src_ring->base_addr_ce_space); src_ring->base_addr_ce_space);
ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries);
ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max); ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max);
...@@ -1385,7 +1430,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, ...@@ -1385,7 +1430,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr); ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
dest_ring->write_index &= dest_ring->nentries_mask; dest_ring->write_index &= dest_ring->nentries_mask;
ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, ath10k_ce_dest_ring_base_addr_set(ar, ce_id,
dest_ring->base_addr_ce_space); dest_ring->base_addr_ce_space);
ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries);
ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0);
...@@ -1661,7 +1706,7 @@ static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id) ...@@ -1661,7 +1706,7 @@ static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id)
{ {
u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id); u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id);
ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_base_addr_set(ar, ce_id, 0);
ath10k_ce_src_ring_size_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_size_set(ar, ctrl_addr, 0);
ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, 0);
ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, 0);
...@@ -1671,7 +1716,7 @@ static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id) ...@@ -1671,7 +1716,7 @@ static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id)
{ {
u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id); u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id);
ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_base_addr_set(ar, ce_id, 0);
ath10k_ce_dest_ring_size_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, 0);
ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, 0);
} }
...@@ -1803,6 +1848,8 @@ static const struct ath10k_ce_ops ce_ops = { ...@@ -1803,6 +1848,8 @@ static const struct ath10k_ce_ops ce_ops = {
.ce_extract_desc_data = ath10k_ce_extract_desc_data, .ce_extract_desc_data = ath10k_ce_extract_desc_data,
.ce_free_pipe = _ath10k_ce_free_pipe, .ce_free_pipe = _ath10k_ce_free_pipe,
.ce_send_nolock = _ath10k_ce_send_nolock, .ce_send_nolock = _ath10k_ce_send_nolock,
.ce_set_src_ring_base_addr_hi = NULL,
.ce_set_dest_ring_base_addr_hi = NULL,
}; };
static const struct ath10k_ce_ops ce_64_ops = { static const struct ath10k_ce_ops ce_64_ops = {
...@@ -1815,6 +1862,8 @@ static const struct ath10k_ce_ops ce_64_ops = { ...@@ -1815,6 +1862,8 @@ static const struct ath10k_ce_ops ce_64_ops = {
.ce_extract_desc_data = ath10k_ce_extract_desc_data_64, .ce_extract_desc_data = ath10k_ce_extract_desc_data_64,
.ce_free_pipe = _ath10k_ce_free_pipe_64, .ce_free_pipe = _ath10k_ce_free_pipe_64,
.ce_send_nolock = _ath10k_ce_send_nolock_64, .ce_send_nolock = _ath10k_ce_send_nolock_64,
.ce_set_src_ring_base_addr_hi = ath10k_ce_set_src_ring_base_addr_hi,
.ce_set_dest_ring_base_addr_hi = ath10k_ce_set_dest_ring_base_addr_hi,
}; };
static void ath10k_ce_set_ops(struct ath10k *ar, static void ath10k_ce_set_ops(struct ath10k *ar,
...@@ -1910,7 +1959,7 @@ void ath10k_ce_alloc_rri(struct ath10k *ar) ...@@ -1910,7 +1959,7 @@ void ath10k_ce_alloc_rri(struct ath10k *ar)
lower_32_bits(ce->paddr_rri)); lower_32_bits(ce->paddr_rri));
ath10k_ce_write32(ar, ar->hw_ce_regs->ce_rri_high, ath10k_ce_write32(ar, ar->hw_ce_regs->ce_rri_high,
(upper_32_bits(ce->paddr_rri) & (upper_32_bits(ce->paddr_rri) &
CE_DESC_FLAGS_GET_MASK)); CE_DESC_ADDR_HI_MASK));
for (i = 0; i < CE_COUNT; i++) { for (i = 0; i < CE_COUNT; i++) {
ctrl1_regs = ar->hw_ce_regs->ctrl1_regs->addr; ctrl1_regs = ar->hw_ce_regs->ctrl1_regs->addr;
......
...@@ -39,8 +39,8 @@ struct ath10k_ce_pipe; ...@@ -39,8 +39,8 @@ struct ath10k_ce_pipe;
#define CE_DESC_FLAGS_BYTE_SWAP (1 << 1) #define CE_DESC_FLAGS_BYTE_SWAP (1 << 1)
#define CE_WCN3990_DESC_FLAGS_GATHER BIT(31) #define CE_WCN3990_DESC_FLAGS_GATHER BIT(31)
#define CE_DESC_FLAGS_GET_MASK GENMASK(4, 0) #define CE_DESC_ADDR_MASK GENMASK_ULL(34, 0)
#define CE_DESC_37BIT_ADDR_MASK GENMASK_ULL(37, 0) #define CE_DESC_ADDR_HI_MASK GENMASK(4, 0)
/* Following desc flags are used in QCA99X0 */ /* Following desc flags are used in QCA99X0 */
#define CE_DESC_FLAGS_HOST_INT_DIS (1 << 2) #define CE_DESC_FLAGS_HOST_INT_DIS (1 << 2)
...@@ -104,7 +104,7 @@ struct ath10k_ce_ring { ...@@ -104,7 +104,7 @@ struct ath10k_ce_ring {
/* Host address space */ /* Host address space */
void *base_addr_owner_space_unaligned; void *base_addr_owner_space_unaligned;
/* CE address space */ /* CE address space */
u32 base_addr_ce_space_unaligned; dma_addr_t base_addr_ce_space_unaligned;
/* /*
* Actual start of descriptors. * Actual start of descriptors.
...@@ -115,7 +115,7 @@ struct ath10k_ce_ring { ...@@ -115,7 +115,7 @@ struct ath10k_ce_ring {
void *base_addr_owner_space; void *base_addr_owner_space;
/* CE address space */ /* CE address space */
u32 base_addr_ce_space; dma_addr_t base_addr_ce_space;
char *shadow_base_unaligned; char *shadow_base_unaligned;
struct ce_desc *shadow_base; struct ce_desc *shadow_base;
...@@ -334,6 +334,12 @@ struct ath10k_ce_ops { ...@@ -334,6 +334,12 @@ struct ath10k_ce_ops {
void *per_transfer_context, void *per_transfer_context,
dma_addr_t buffer, u32 nbytes, dma_addr_t buffer, u32 nbytes,
u32 transfer_id, u32 flags); u32 transfer_id, u32 flags);
void (*ce_set_src_ring_base_addr_hi)(struct ath10k *ar,
u32 ce_ctrl_addr,
u64 addr);
void (*ce_set_dest_ring_base_addr_hi)(struct ath10k *ar,
u32 ce_ctrl_addr,
u64 addr);
}; };
static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id) static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id)
......
...@@ -1498,7 +1498,7 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt, ...@@ -1498,7 +1498,7 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
u16 msdu_id, flags1 = 0; u16 msdu_id, flags1 = 0;
u16 freq = 0; u16 freq = 0;
dma_addr_t frags_paddr = 0; dma_addr_t frags_paddr = 0;
u32 txbuf_paddr; dma_addr_t txbuf_paddr;
struct htt_msdu_ext_desc_64 *ext_desc = NULL; struct htt_msdu_ext_desc_64 *ext_desc = NULL;
struct htt_msdu_ext_desc_64 *ext_desc_t = NULL; struct htt_msdu_ext_desc_64 *ext_desc_t = NULL;
......
...@@ -318,9 +318,11 @@ static struct ath10k_hw_ce_ctrl1_upd wcn3990_ctrl1_upd = { ...@@ -318,9 +318,11 @@ static struct ath10k_hw_ce_ctrl1_upd wcn3990_ctrl1_upd = {
}; };
const struct ath10k_hw_ce_regs wcn3990_ce_regs = { const struct ath10k_hw_ce_regs wcn3990_ce_regs = {
.sr_base_addr = 0x00000000, .sr_base_addr_lo = 0x00000000,
.sr_base_addr_hi = 0x00000004,
.sr_size_addr = 0x00000008, .sr_size_addr = 0x00000008,
.dr_base_addr = 0x0000000c, .dr_base_addr_lo = 0x0000000c,
.dr_base_addr_hi = 0x00000010,
.dr_size_addr = 0x00000014, .dr_size_addr = 0x00000014,
.misc_ie_addr = 0x00000034, .misc_ie_addr = 0x00000034,
.sr_wr_index_addr = 0x0000003c, .sr_wr_index_addr = 0x0000003c,
...@@ -464,9 +466,9 @@ static struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_dst_ring = { ...@@ -464,9 +466,9 @@ static struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_dst_ring = {
}; };
const struct ath10k_hw_ce_regs qcax_ce_regs = { const struct ath10k_hw_ce_regs qcax_ce_regs = {
.sr_base_addr = 0x00000000, .sr_base_addr_lo = 0x00000000,
.sr_size_addr = 0x00000004, .sr_size_addr = 0x00000004,
.dr_base_addr = 0x00000008, .dr_base_addr_lo = 0x00000008,
.dr_size_addr = 0x0000000c, .dr_size_addr = 0x0000000c,
.ce_cmd_addr = 0x00000018, .ce_cmd_addr = 0x00000018,
.misc_ie_addr = 0x00000034, .misc_ie_addr = 0x00000034,
......
...@@ -353,9 +353,11 @@ struct ath10k_hw_ce_ctrl1_upd { ...@@ -353,9 +353,11 @@ struct ath10k_hw_ce_ctrl1_upd {
}; };
struct ath10k_hw_ce_regs { struct ath10k_hw_ce_regs {
u32 sr_base_addr; u32 sr_base_addr_lo;
u32 sr_base_addr_hi;
u32 sr_size_addr; u32 sr_size_addr;
u32 dr_base_addr; u32 dr_base_addr_lo;
u32 dr_base_addr_hi;
u32 dr_size_addr; u32 dr_size_addr;
u32 ce_cmd_addr; u32 ce_cmd_addr;
u32 misc_ie_addr; u32 misc_ie_addr;
......
...@@ -66,7 +66,7 @@ static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state); ...@@ -66,7 +66,7 @@ static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state);
static const struct ath10k_snoc_drv_priv drv_priv = { static const struct ath10k_snoc_drv_priv drv_priv = {
.hw_rev = ATH10K_HW_WCN3990, .hw_rev = ATH10K_HW_WCN3990,
.dma_mask = DMA_BIT_MASK(37), .dma_mask = DMA_BIT_MASK(35),
.msa_size = 0x100000, .msa_size = 0x100000,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment