diff options
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/pmc.c')
| -rw-r--r-- | drivers/net/wireless/ath/wil6210/pmc.c | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c index 2e301b6b32a9..a2f7b4c1da48 100644 --- a/drivers/net/wireless/ath/wil6210/pmc.c +++ b/drivers/net/wireless/ath/wil6210/pmc.c @@ -1,22 +1,13 @@ +// SPDX-License-Identifier: ISC /* * Copyright (c) 2012-2015,2017 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ #include <linux/types.h> #include <linux/errno.h> #include <linux/fs.h> +#include <linux/seq_file.h> #include "wmi.h" #include "wil6210.h" #include "txrx.h" @@ -38,8 +29,7 @@ void wil_pmc_init(struct wil6210_priv *wil) mutex_init(&wil->pmc.lock); } -/** - * Allocate the physical ring (p-ring) and the required +/* Allocate the physical ring (p-ring) and the required * number of descriptors of required size. * Initialize the descriptors as required by pmc dma. * The descriptors' buffers dwords are initialized to hold @@ -53,6 +43,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil, u32 i; struct pmc_ctx *pmc = &wil->pmc; struct device *dev = wil_to_dev(wil); + struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); struct wmi_pmc_cmd pmc_cmd = {0}; int last_cmd_err = -ENOMEM; @@ -111,14 +102,14 @@ void wil_pmc_alloc(struct wil6210_priv *wil, * * HW has limitation that all vrings addresses must share the same * upper 16 msb bits part of 48 bits address. To workaround that, - * if we are using 48 bit addresses switch to 32 bit allocation - * before allocating vring memory. + * if we are using more than 32 bit addresses switch to 32 bit + * allocation before allocating vring memory. * * There's no check for the return value of dma_set_mask_and_coherent, * since we assume if we were able to set the mask during * initialization in this system it will not fail if we set it again */ - if (wil->use_extended_dma_addr) + if (wil->dma_addr_size > 32) dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); pmc->pring_va = dma_alloc_coherent(dev, @@ -126,8 +117,9 @@ void wil_pmc_alloc(struct wil6210_priv *wil, &pmc->pring_pa, GFP_KERNEL); - if (wil->use_extended_dma_addr) - dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); + if (wil->dma_addr_size > 32) + dma_set_mask_and_coherent(dev, + DMA_BIT_MASK(wil->dma_addr_size)); wil_dbg_misc(wil, "pmc_alloc: allocated pring %p => %pad. %zd x %d = total %zd bytes\n", @@ -185,6 +177,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil, wil_dbg_misc(wil, "pmc_alloc: send WMI_PMC_CMD with ALLOCATE op\n"); pmc->last_cmd_status = wmi_send(wil, WMI_PMC_CMDID, + vif->mid, &pmc_cmd, sizeof(pmc_cmd)); if (pmc->last_cmd_status) { @@ -227,14 +220,14 @@ no_release_err: mutex_unlock(&pmc->lock); } -/** - * Traverse the p-ring and release all buffers. +/* Traverse the p-ring and release all buffers. * At the end release the p-ring memory */ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd) { struct pmc_ctx *pmc = &wil->pmc; struct device *dev = wil_to_dev(wil); + struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); struct wmi_pmc_cmd pmc_cmd = {0}; mutex_lock(&pmc->lock); @@ -253,8 +246,8 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd) wil_dbg_misc(wil, "send WMI_PMC_CMD with RELEASE op\n"); pmc_cmd.op = WMI_PMC_RELEASE; pmc->last_cmd_status = - wmi_send(wil, WMI_PMC_CMDID, &pmc_cmd, - sizeof(pmc_cmd)); + wmi_send(wil, WMI_PMC_CMDID, vif->mid, + &pmc_cmd, sizeof(pmc_cmd)); if (pmc->last_cmd_status) { wil_err(wil, "WMI_PMC_CMD with RELEASE op failed, status %d", @@ -304,8 +297,7 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd) mutex_unlock(&pmc->lock); } -/** - * Status of the last operation requested via debugfs: alloc/free/read. +/* Status of the last operation requested via debugfs: alloc/free/read. * 0 - success or negative errno */ int wil_pmc_last_cmd_status(struct wil6210_priv *wil) @@ -316,8 +308,7 @@ int wil_pmc_last_cmd_status(struct wil6210_priv *wil) return wil->pmc.last_cmd_status; } -/** - * Read from required position up to the end of current descriptor, +/* Read from required position up to the end of current descriptor, * depends on descriptor size configured during alloc request. */ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count, @@ -426,3 +417,28 @@ out: return newpos; } + +int wil_pmcring_read(struct seq_file *s, void *data) +{ + struct wil6210_priv *wil = s->private; + struct pmc_ctx *pmc = &wil->pmc; + size_t pmc_ring_size = + sizeof(struct vring_rx_desc) * pmc->num_descriptors; + + mutex_lock(&pmc->lock); + + if (!wil_is_pmc_allocated(pmc)) { + wil_err(wil, "error, pmc is not allocated!\n"); + pmc->last_cmd_status = -EPERM; + mutex_unlock(&pmc->lock); + return -EPERM; + } + + wil_dbg_misc(wil, "pmcring_read: size %zu\n", pmc_ring_size); + + seq_write(s, pmc->pring_va, pmc_ring_size); + + mutex_unlock(&pmc->lock); + + return 0; +} |
