1 // SPDX-License-Identifier: ISC
3 * Copyright (c) 2012-2015,2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
7 #include <linux/types.h>
8 #include <linux/errno.h>
10 #include <linux/seq_file.h>
16 struct desc_alloc_info
{
21 static int wil_is_pmc_allocated(struct pmc_ctx
*pmc
)
23 return !!pmc
->pring_va
;
26 void wil_pmc_init(struct wil6210_priv
*wil
)
28 memset(&wil
->pmc
, 0, sizeof(struct pmc_ctx
));
29 mutex_init(&wil
->pmc
.lock
);
32 /* Allocate the physical ring (p-ring) and the required
33 * number of descriptors of required size.
34 * Initialize the descriptors as required by pmc dma.
35 * The descriptors' buffers dwords are initialized to hold
36 * dword's serial number in the lsw and reserved value
37 * PCM_DATA_INVALID_DW_VAL in the msw.
39 void wil_pmc_alloc(struct wil6210_priv
*wil
,
44 struct pmc_ctx
*pmc
= &wil
->pmc
;
45 struct device
*dev
= wil_to_dev(wil
);
46 struct wil6210_vif
*vif
= ndev_to_vif(wil
->main_ndev
);
47 struct wmi_pmc_cmd pmc_cmd
= {0};
48 int last_cmd_err
= -ENOMEM
;
50 mutex_lock(&pmc
->lock
);
52 if (wil_is_pmc_allocated(pmc
)) {
54 wil_err(wil
, "ERROR pmc is already allocated\n");
57 if ((num_descriptors
<= 0) || (descriptor_size
<= 0)) {
59 "Invalid params num_descriptors(%d), descriptor_size(%d)\n",
60 num_descriptors
, descriptor_size
);
61 last_cmd_err
= -EINVAL
;
65 if (num_descriptors
> (1 << WIL_RING_SIZE_ORDER_MAX
)) {
67 "num_descriptors(%d) exceeds max ring size %d\n",
68 num_descriptors
, 1 << WIL_RING_SIZE_ORDER_MAX
);
69 last_cmd_err
= -EINVAL
;
73 if (num_descriptors
> INT_MAX
/ descriptor_size
) {
75 "Overflow in num_descriptors(%d)*descriptor_size(%d)\n",
76 num_descriptors
, descriptor_size
);
77 last_cmd_err
= -EINVAL
;
81 pmc
->num_descriptors
= num_descriptors
;
82 pmc
->descriptor_size
= descriptor_size
;
84 wil_dbg_misc(wil
, "pmc_alloc: %d descriptors x %d bytes each\n",
85 num_descriptors
, descriptor_size
);
87 /* allocate descriptors info list in pmc context*/
88 pmc
->descriptors
= kcalloc(num_descriptors
,
89 sizeof(struct desc_alloc_info
),
91 if (!pmc
->descriptors
) {
92 wil_err(wil
, "ERROR allocating pmc skb list\n");
96 wil_dbg_misc(wil
, "pmc_alloc: allocated descriptors info list %p\n",
99 /* Allocate pring buffer and descriptors.
100 * vring->va should be aligned on its size rounded up to power of 2
101 * This is granted by the dma_alloc_coherent.
103 * HW has limitation that all vrings addresses must share the same
104 * upper 16 msb bits part of 48 bits address. To workaround that,
105 * if we are using more than 32 bit addresses switch to 32 bit
106 * allocation before allocating vring memory.
108 * There's no check for the return value of dma_set_mask_and_coherent,
109 * since we assume if we were able to set the mask during
110 * initialization in this system it will not fail if we set it again
112 if (wil
->dma_addr_size
> 32)
113 dma_set_mask_and_coherent(dev
, DMA_BIT_MASK(32));
115 pmc
->pring_va
= dma_alloc_coherent(dev
,
116 sizeof(struct vring_tx_desc
) * num_descriptors
,
120 if (wil
->dma_addr_size
> 32)
121 dma_set_mask_and_coherent(dev
,
122 DMA_BIT_MASK(wil
->dma_addr_size
));
125 "pmc_alloc: allocated pring %p => %pad. %zd x %d = total %zd bytes\n",
126 pmc
->pring_va
, &pmc
->pring_pa
,
127 sizeof(struct vring_tx_desc
),
129 sizeof(struct vring_tx_desc
) * num_descriptors
);
131 if (!pmc
->pring_va
) {
132 wil_err(wil
, "ERROR allocating pmc pring\n");
133 goto release_pmc_skb_list
;
136 /* initially, all descriptors are SW owned
137 * For Tx, Rx, and PMC, ownership bit is at the same location, thus
140 for (i
= 0; i
< num_descriptors
; i
++) {
141 struct vring_tx_desc
*_d
= &pmc
->pring_va
[i
];
142 struct vring_tx_desc dd
= {}, *d
= &dd
;
145 pmc
->descriptors
[i
].va
= dma_alloc_coherent(dev
,
147 &pmc
->descriptors
[i
].pa
,
150 if (unlikely(!pmc
->descriptors
[i
].va
)) {
151 wil_err(wil
, "ERROR allocating pmc descriptor %d", i
);
152 goto release_pmc_skbs
;
155 for (j
= 0; j
< descriptor_size
/ sizeof(u32
); j
++) {
156 u32
*p
= (u32
*)pmc
->descriptors
[i
].va
+ j
;
157 *p
= PCM_DATA_INVALID_DW_VAL
| j
;
160 /* configure dma descriptor */
161 d
->dma
.addr
.addr_low
=
162 cpu_to_le32(lower_32_bits(pmc
->descriptors
[i
].pa
));
163 d
->dma
.addr
.addr_high
=
164 cpu_to_le16((u16
)upper_32_bits(pmc
->descriptors
[i
].pa
));
165 d
->dma
.status
= 0; /* 0 = HW_OWNED */
166 d
->dma
.length
= cpu_to_le16(descriptor_size
);
167 d
->dma
.d0
= BIT(9) | RX_DMA_D0_CMD_DMA_IT
;
171 wil_dbg_misc(wil
, "pmc_alloc: allocated successfully\n");
173 pmc_cmd
.op
= WMI_PMC_ALLOCATE
;
174 pmc_cmd
.ring_size
= cpu_to_le16(pmc
->num_descriptors
);
175 pmc_cmd
.mem_base
= cpu_to_le64(pmc
->pring_pa
);
177 wil_dbg_misc(wil
, "pmc_alloc: send WMI_PMC_CMD with ALLOCATE op\n");
178 pmc
->last_cmd_status
= wmi_send(wil
,
183 if (pmc
->last_cmd_status
) {
185 "WMI_PMC_CMD with ALLOCATE op failed with status %d",
186 pmc
->last_cmd_status
);
187 goto release_pmc_skbs
;
190 mutex_unlock(&pmc
->lock
);
195 wil_err(wil
, "exit on error: Releasing skbs...\n");
196 for (i
= 0; i
< num_descriptors
&& pmc
->descriptors
[i
].va
; i
++) {
197 dma_free_coherent(dev
,
199 pmc
->descriptors
[i
].va
,
200 pmc
->descriptors
[i
].pa
);
202 pmc
->descriptors
[i
].va
= NULL
;
204 wil_err(wil
, "exit on error: Releasing pring...\n");
206 dma_free_coherent(dev
,
207 sizeof(struct vring_tx_desc
) * num_descriptors
,
211 pmc
->pring_va
= NULL
;
213 release_pmc_skb_list
:
214 wil_err(wil
, "exit on error: Releasing descriptors info list...\n");
215 kfree(pmc
->descriptors
);
216 pmc
->descriptors
= NULL
;
219 pmc
->last_cmd_status
= last_cmd_err
;
220 mutex_unlock(&pmc
->lock
);
223 /* Traverse the p-ring and release all buffers.
224 * At the end release the p-ring memory
226 void wil_pmc_free(struct wil6210_priv
*wil
, int send_pmc_cmd
)
228 struct pmc_ctx
*pmc
= &wil
->pmc
;
229 struct device
*dev
= wil_to_dev(wil
);
230 struct wil6210_vif
*vif
= ndev_to_vif(wil
->main_ndev
);
231 struct wmi_pmc_cmd pmc_cmd
= {0};
233 mutex_lock(&pmc
->lock
);
235 pmc
->last_cmd_status
= 0;
237 if (!wil_is_pmc_allocated(pmc
)) {
239 "pmc_free: Error, can't free - not allocated\n");
240 pmc
->last_cmd_status
= -EPERM
;
241 mutex_unlock(&pmc
->lock
);
246 wil_dbg_misc(wil
, "send WMI_PMC_CMD with RELEASE op\n");
247 pmc_cmd
.op
= WMI_PMC_RELEASE
;
248 pmc
->last_cmd_status
=
249 wmi_send(wil
, WMI_PMC_CMDID
, vif
->mid
,
250 &pmc_cmd
, sizeof(pmc_cmd
));
251 if (pmc
->last_cmd_status
) {
253 "WMI_PMC_CMD with RELEASE op failed, status %d",
254 pmc
->last_cmd_status
);
255 /* There's nothing we can do with this error.
256 * Normally, it should never occur.
257 * Continue to freeing all memory allocated for pmc.
263 size_t buf_size
= sizeof(struct vring_tx_desc
) *
264 pmc
->num_descriptors
;
266 wil_dbg_misc(wil
, "pmc_free: free pring va %p\n",
268 dma_free_coherent(dev
, buf_size
, pmc
->pring_va
, pmc
->pring_pa
);
270 pmc
->pring_va
= NULL
;
272 pmc
->last_cmd_status
= -ENOENT
;
275 if (pmc
->descriptors
) {
279 i
< pmc
->num_descriptors
&& pmc
->descriptors
[i
].va
; i
++) {
280 dma_free_coherent(dev
,
281 pmc
->descriptor_size
,
282 pmc
->descriptors
[i
].va
,
283 pmc
->descriptors
[i
].pa
);
284 pmc
->descriptors
[i
].va
= NULL
;
286 wil_dbg_misc(wil
, "pmc_free: free descriptor info %d/%d\n", i
,
287 pmc
->num_descriptors
);
289 "pmc_free: free pmc descriptors info list %p\n",
291 kfree(pmc
->descriptors
);
292 pmc
->descriptors
= NULL
;
294 pmc
->last_cmd_status
= -ENOENT
;
297 mutex_unlock(&pmc
->lock
);
300 /* Status of the last operation requested via debugfs: alloc/free/read.
301 * 0 - success or negative errno
303 int wil_pmc_last_cmd_status(struct wil6210_priv
*wil
)
305 wil_dbg_misc(wil
, "pmc_last_cmd_status: status %d\n",
306 wil
->pmc
.last_cmd_status
);
308 return wil
->pmc
.last_cmd_status
;
311 /* Read from required position up to the end of current descriptor,
312 * depends on descriptor size configured during alloc request.
314 ssize_t
wil_pmc_read(struct file
*filp
, char __user
*buf
, size_t count
,
317 struct wil6210_priv
*wil
= filp
->private_data
;
318 struct pmc_ctx
*pmc
= &wil
->pmc
;
320 unsigned long long idx
;
324 mutex_lock(&pmc
->lock
);
326 if (!wil_is_pmc_allocated(pmc
)) {
327 wil_err(wil
, "error, pmc is not allocated!\n");
328 pmc
->last_cmd_status
= -EPERM
;
329 mutex_unlock(&pmc
->lock
);
333 pmc_size
= pmc
->descriptor_size
* pmc
->num_descriptors
;
336 "pmc_read: size %u, pos %lld\n",
339 pmc
->last_cmd_status
= 0;
342 do_div(idx
, pmc
->descriptor_size
);
343 offset
= *f_pos
- (idx
* pmc
->descriptor_size
);
345 if (*f_pos
>= pmc_size
) {
347 "pmc_read: reached end of pmc buf: %lld >= %u\n",
348 *f_pos
, (u32
)pmc_size
);
349 pmc
->last_cmd_status
= -ERANGE
;
354 "pmc_read: read from pos %lld (descriptor %llu, offset %llu) %zu bytes\n",
355 *f_pos
, idx
, offset
, count
);
357 /* if no errors, return the copied byte count */
358 retval
= simple_read_from_buffer(buf
,
361 pmc
->descriptors
[idx
].va
,
362 pmc
->descriptor_size
);
365 mutex_unlock(&pmc
->lock
);
370 loff_t
wil_pmc_llseek(struct file
*filp
, loff_t off
, int whence
)
373 struct wil6210_priv
*wil
= filp
->private_data
;
374 struct pmc_ctx
*pmc
= &wil
->pmc
;
377 mutex_lock(&pmc
->lock
);
379 if (!wil_is_pmc_allocated(pmc
)) {
380 wil_err(wil
, "error, pmc is not allocated!\n");
381 pmc
->last_cmd_status
= -EPERM
;
382 mutex_unlock(&pmc
->lock
);
386 pmc_size
= pmc
->descriptor_size
* pmc
->num_descriptors
;
389 case 0: /* SEEK_SET */
393 case 1: /* SEEK_CUR */
394 newpos
= filp
->f_pos
+ off
;
397 case 2: /* SEEK_END */
401 default: /* can't happen */
410 if (newpos
> pmc_size
)
413 filp
->f_pos
= newpos
;
416 mutex_unlock(&pmc
->lock
);
421 int wil_pmcring_read(struct seq_file
*s
, void *data
)
423 struct wil6210_priv
*wil
= s
->private;
424 struct pmc_ctx
*pmc
= &wil
->pmc
;
425 size_t pmc_ring_size
=
426 sizeof(struct vring_rx_desc
) * pmc
->num_descriptors
;
428 mutex_lock(&pmc
->lock
);
430 if (!wil_is_pmc_allocated(pmc
)) {
431 wil_err(wil
, "error, pmc is not allocated!\n");
432 pmc
->last_cmd_status
= -EPERM
;
433 mutex_unlock(&pmc
->lock
);
437 wil_dbg_misc(wil
, "pmcring_read: size %zu\n", pmc_ring_size
);
439 seq_write(s
, pmc
->pring_va
, pmc_ring_size
);
441 mutex_unlock(&pmc
->lock
);