ath9k: Allow configuration of LED polarity in platform data.
[oweals/openwrt.git] / package / kernel / mac80211 / patches / 303-ath10k-do-not-use-coherent-memory-for-allocated-devi.patch
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
4  memory chunks
5
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
9 memory spaces
10
11 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
12 ---
13
14 --- a/drivers/net/wireless/ath/ath10k/wmi.c
15 +++ b/drivers/net/wireless/ath/ath10k/wmi.c
16 @@ -4312,34 +4312,58 @@ void ath10k_wmi_event_vdev_resume_req(st
17         ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n");
18  }
19  
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)
24  {
25         dma_addr_t paddr;
26 -       u32 pool_size;
27 +       u32 pool_size = 0;
28         int idx = ar->wmi.num_mem_chunks;
29 +       void *vaddr = NULL;
30  
31 -       pool_size = num_units * round_up(unit_len, 4);
32 +       if (ar->wmi.num_mem_chunks == ARRAY_SIZE(ar->wmi.mem_chunks))
33 +               return -ENOMEM;
34  
35 -       if (!pool_size)
36 -               return -EINVAL;
37 +       while (!vaddr && num_units) {
38 +               pool_size = num_units * round_up(unit_len, 4);
39 +               if (!pool_size)
40 +                       return -EINVAL;
41  
42 -       ar->wmi.mem_chunks[idx].vaddr = dma_alloc_coherent(ar->dev,
43 -                                                          pool_size,
44 -                                                          &paddr,
45 -                                                          GFP_KERNEL);
46 -       if (!ar->wmi.mem_chunks[idx].vaddr) {
47 -               ath10k_warn(ar, "failed to allocate memory chunk\n");
48 -               return -ENOMEM;
49 +               vaddr = kzalloc(pool_size, GFP_KERNEL | __GFP_NOWARN);
50 +               if (!vaddr)
51 +                       num_units /= 2;
52         }
53  
54 -       memset(ar->wmi.mem_chunks[idx].vaddr, 0, pool_size);
55 +       if (!num_units)
56 +               return -ENOMEM;
57 +
58 +       paddr = dma_map_single(ar->dev, vaddr, pool_size, DMA_TO_DEVICE);
59 +       if (dma_mapping_error(ar->dev, paddr)) {
60 +               kfree(vaddr);
61 +               return -ENOMEM;
62 +       }
63  
64 +       ar->wmi.mem_chunks[idx].vaddr = vaddr;
65         ar->wmi.mem_chunks[idx].paddr = paddr;
66         ar->wmi.mem_chunks[idx].len = pool_size;
67         ar->wmi.mem_chunks[idx].req_id = req_id;
68         ar->wmi.num_mem_chunks++;
69  
70 +       return num_units;
71 +}
72 +
73 +static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
74 +                                    u32 num_units, u32 unit_len)
75 +{
76 +       int ret;
77 +
78 +       while (num_units) {
79 +               ret = ath10k_wmi_alloc_chunk(ar, req_id, num_units, unit_len);
80 +               if (ret < 0)
81 +                       return ret;
82 +
83 +               num_units -= ret;
84 +       }
85 +
86         return 0;
87  }
88  
89 @@ -7717,10 +7741,11 @@ void ath10k_wmi_free_host_mem(struct ath
90  
91         /* free the host memory chunks requested by firmware */
92         for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
93 -               dma_free_coherent(ar->dev,
94 -                                 ar->wmi.mem_chunks[i].len,
95 -                                 ar->wmi.mem_chunks[i].vaddr,
96 -                                 ar->wmi.mem_chunks[i].paddr);
97 +               dma_unmap_single(ar->dev,
98 +                                ar->wmi.mem_chunks[i].paddr,
99 +                                ar->wmi.mem_chunks[i].len,
100 +                                DMA_TO_DEVICE);
101 +               kfree(ar->wmi.mem_chunks[i].vaddr);
102         }
103  
104         ar->wmi.num_mem_chunks = 0;