1 From: Felix Fietkau <nbd@openwrt.org>
2 Date: Sun, 22 Nov 2015 14:03:40 +0100
3 Subject: [PATCH] ath10k: do not use coherent memory for allocated device
6 Coherent memory is more expensive to allocate (and constrained on some
7 architectures where it has to be pre-allocated). It is also completely
8 unnecessary, since the host has no reason to even access these allocated
11 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
14 --- a/drivers/net/wireless/ath/ath10k/wmi.c
15 +++ b/drivers/net/wireless/ath/ath10k/wmi.c
16 @@ -4258,34 +4258,58 @@ void ath10k_wmi_event_vdev_resume_req(st
17 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n");
20 -static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
21 - u32 num_units, u32 unit_len)
22 +static int ath10k_wmi_alloc_chunk(struct ath10k *ar, u32 req_id,
23 + u32 num_units, u32 unit_len)
27 int idx = ar->wmi.num_mem_chunks;
30 - pool_size = num_units * round_up(unit_len, 4);
31 + if (ar->wmi.num_mem_chunks == ARRAY_SIZE(ar->wmi.mem_chunks))
36 + while (!vaddr && num_units) {
37 + pool_size = num_units * round_up(unit_len, 4);
41 - ar->wmi.mem_chunks[idx].vaddr = dma_alloc_coherent(ar->dev,
45 - if (!ar->wmi.mem_chunks[idx].vaddr) {
46 - ath10k_warn(ar, "failed to allocate memory chunk\n");
48 + vaddr = kzalloc(pool_size, GFP_KERNEL | __GFP_NOWARN);
53 - memset(ar->wmi.mem_chunks[idx].vaddr, 0, pool_size);
57 + paddr = dma_map_single(ar->dev, vaddr, pool_size, DMA_TO_DEVICE);
58 + if (dma_mapping_error(ar->dev, paddr)) {
63 + ar->wmi.mem_chunks[idx].vaddr = vaddr;
64 ar->wmi.mem_chunks[idx].paddr = paddr;
65 ar->wmi.mem_chunks[idx].len = pool_size;
66 ar->wmi.mem_chunks[idx].req_id = req_id;
67 ar->wmi.num_mem_chunks++;
72 +static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
73 + u32 num_units, u32 unit_len)
78 + ret = ath10k_wmi_alloc_chunk(ar, req_id, num_units, unit_len);
88 @@ -7616,10 +7640,11 @@ void ath10k_wmi_free_host_mem(struct ath
90 /* free the host memory chunks requested by firmware */
91 for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
92 - dma_free_coherent(ar->dev,
93 - ar->wmi.mem_chunks[i].len,
94 - ar->wmi.mem_chunks[i].vaddr,
95 - ar->wmi.mem_chunks[i].paddr);
96 + dma_unmap_single(ar->dev,
97 + ar->wmi.mem_chunks[i].paddr,
98 + ar->wmi.mem_chunks[i].len,
100 + kfree(ar->wmi.mem_chunks[i].vaddr);
103 ar->wmi.num_mem_chunks = 0;