linux/drivers/net/wireless/ath/wil6210/pmc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: ISC
   2/*
   3 * Copyright (c) 2012-2015,2017 Qualcomm Atheros, Inc.
   4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
   5 */
   6
   7#include <linux/types.h>
   8#include <linux/errno.h>
   9#include <linux/fs.h>
  10#include <linux/seq_file.h>
  11#include "wmi.h"
  12#include "wil6210.h"
  13#include "txrx.h"
  14#include "pmc.h"
  15
  16struct desc_alloc_info {
  17        dma_addr_t pa;
  18        void      *va;
  19};
  20
  21static int wil_is_pmc_allocated(struct pmc_ctx *pmc)
  22{
  23        return !!pmc->pring_va;
  24}
  25
  26void wil_pmc_init(struct wil6210_priv *wil)
  27{
  28        memset(&wil->pmc, 0, sizeof(struct pmc_ctx));
  29        mutex_init(&wil->pmc.lock);
  30}
  31
  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.
  38 */
  39void wil_pmc_alloc(struct wil6210_priv *wil,
  40                   int num_descriptors,
  41                   int descriptor_size)
  42{
  43        u32 i;
  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;
  49
  50        mutex_lock(&pmc->lock);
  51
  52        if (wil_is_pmc_allocated(pmc)) {
  53                /* sanity check */
  54                wil_err(wil, "ERROR pmc is already allocated\n");
  55                goto no_release_err;
  56        }
  57        if ((num_descriptors <= 0) || (descriptor_size <= 0)) {
  58                wil_err(wil,
  59                        "Invalid params num_descriptors(%d), descriptor_size(%d)\n",
  60                        num_descriptors, descriptor_size);
  61                last_cmd_err = -EINVAL;
  62                goto no_release_err;
  63        }
  64
  65        if (num_descriptors > (1 << WIL_RING_SIZE_ORDER_MAX)) {
  66                wil_err(wil,
  67                        "num_descriptors(%d) exceeds max ring size %d\n",
  68                        num_descriptors, 1 << WIL_RING_SIZE_ORDER_MAX);
  69                last_cmd_err = -EINVAL;
  70                goto no_release_err;
  71        }
  72
  73        if (num_descriptors > INT_MAX / descriptor_size) {
  74                wil_err(wil,
  75                        "Overflow in num_descriptors(%d)*descriptor_size(%d)\n",
  76                        num_descriptors, descriptor_size);
  77                last_cmd_err = -EINVAL;
  78                goto no_release_err;
  79        }
  80
  81        pmc->num_descriptors = num_descriptors;
  82        pmc->descriptor_size = descriptor_size;
  83
  84        wil_dbg_misc(wil, "pmc_alloc: %d descriptors x %d bytes each\n",
  85                     num_descriptors, descriptor_size);
  86
  87        /* allocate descriptors info list in pmc context*/
  88        pmc->descriptors = kcalloc(num_descriptors,
  89                                  sizeof(struct desc_alloc_info),
  90                                  GFP_KERNEL);
  91        if (!pmc->descriptors) {
  92                wil_err(wil, "ERROR allocating pmc skb list\n");
  93                goto no_release_err;
  94        }
  95
  96        wil_dbg_misc(wil, "pmc_alloc: allocated descriptors info list %p\n",
  97                     pmc->descriptors);
  98
  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.
 102         *
 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.
 107         *
 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
 111         */
 112        if (wil->dma_addr_size > 32)
 113                dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 114
 115        pmc->pring_va = dma_alloc_coherent(dev,
 116                        sizeof(struct vring_tx_desc) * num_descriptors,
 117                        &pmc->pring_pa,
 118                        GFP_KERNEL);
 119
 120        if (wil->dma_addr_size > 32)
 121                dma_set_mask_and_coherent(dev,
 122                                          DMA_BIT_MASK(wil->dma_addr_size));
 123
 124        wil_dbg_misc(wil,
 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),
 128                     num_descriptors,
 129                     sizeof(struct vring_tx_desc) * num_descriptors);
 130
 131        if (!pmc->pring_va) {
 132                wil_err(wil, "ERROR allocating pmc pring\n");
 133                goto release_pmc_skb_list;
 134        }
 135
 136        /* initially, all descriptors are SW owned
 137         * For Tx, Rx, and PMC, ownership bit is at the same location, thus
 138         * we can use any
 139         */
 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;
 143                int j = 0;
 144
 145                pmc->descriptors[i].va = dma_alloc_coherent(dev,
 146                        descriptor_size,
 147                        &pmc->descriptors[i].pa,
 148                        GFP_KERNEL);
 149
 150                if (unlikely(!pmc->descriptors[i].va)) {
 151                        wil_err(wil, "ERROR allocating pmc descriptor %d", i);
 152                        goto release_pmc_skbs;
 153                }
 154
 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;
 158                }
 159
 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;
 168                *_d = *d;
 169        }
 170
 171        wil_dbg_misc(wil, "pmc_alloc: allocated successfully\n");
 172
 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);
 176
 177        wil_dbg_misc(wil, "pmc_alloc: send WMI_PMC_CMD with ALLOCATE op\n");
 178        pmc->last_cmd_status = wmi_send(wil,
 179                                        WMI_PMC_CMDID,
 180                                        vif->mid,
 181                                        &pmc_cmd,
 182                                        sizeof(pmc_cmd));
 183        if (pmc->last_cmd_status) {
 184                wil_err(wil,
 185                        "WMI_PMC_CMD with ALLOCATE op failed with status %d",
 186                        pmc->last_cmd_status);
 187                goto release_pmc_skbs;
 188        }
 189
 190        mutex_unlock(&pmc->lock);
 191
 192        return;
 193
 194release_pmc_skbs:
 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,
 198                                  descriptor_size,
 199                                  pmc->descriptors[i].va,
 200                                  pmc->descriptors[i].pa);
 201
 202                pmc->descriptors[i].va = NULL;
 203        }
 204        wil_err(wil, "exit on error: Releasing pring...\n");
 205
 206        dma_free_coherent(dev,
 207                          sizeof(struct vring_tx_desc) * num_descriptors,
 208                          pmc->pring_va,
 209                          pmc->pring_pa);
 210
 211        pmc->pring_va = NULL;
 212
 213release_pmc_skb_list:
 214        wil_err(wil, "exit on error: Releasing descriptors info list...\n");
 215        kfree(pmc->descriptors);
 216        pmc->descriptors = NULL;
 217
 218no_release_err:
 219        pmc->last_cmd_status = last_cmd_err;
 220        mutex_unlock(&pmc->lock);
 221}
 222
 223/* Traverse the p-ring and release all buffers.
 224 * At the end release the p-ring memory
 225 */
 226void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
 227{
 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};
 232
 233        mutex_lock(&pmc->lock);
 234
 235        pmc->last_cmd_status = 0;
 236
 237        if (!wil_is_pmc_allocated(pmc)) {
 238                wil_dbg_misc(wil,
 239                             "pmc_free: Error, can't free - not allocated\n");
 240                pmc->last_cmd_status = -EPERM;
 241                mutex_unlock(&pmc->lock);
 242                return;
 243        }
 244
 245        if (send_pmc_cmd) {
 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) {
 252                        wil_err(wil,
 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.
 258                         */
 259                }
 260        }
 261
 262        if (pmc->pring_va) {
 263                size_t buf_size = sizeof(struct vring_tx_desc) *
 264                                  pmc->num_descriptors;
 265
 266                wil_dbg_misc(wil, "pmc_free: free pring va %p\n",
 267                             pmc->pring_va);
 268                dma_free_coherent(dev, buf_size, pmc->pring_va, pmc->pring_pa);
 269
 270                pmc->pring_va = NULL;
 271        } else {
 272                pmc->last_cmd_status = -ENOENT;
 273        }
 274
 275        if (pmc->descriptors) {
 276                int i;
 277
 278                for (i = 0;
 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;
 285                }
 286                wil_dbg_misc(wil, "pmc_free: free descriptor info %d/%d\n", i,
 287                             pmc->num_descriptors);
 288                wil_dbg_misc(wil,
 289                             "pmc_free: free pmc descriptors info list %p\n",
 290                             pmc->descriptors);
 291                kfree(pmc->descriptors);
 292                pmc->descriptors = NULL;
 293        } else {
 294                pmc->last_cmd_status = -ENOENT;
 295        }
 296
 297        mutex_unlock(&pmc->lock);
 298}
 299
 300/* Status of the last operation requested via debugfs: alloc/free/read.
 301 * 0 - success or negative errno
 302 */
 303int wil_pmc_last_cmd_status(struct wil6210_priv *wil)
 304{
 305        wil_dbg_misc(wil, "pmc_last_cmd_status: status %d\n",
 306                     wil->pmc.last_cmd_status);
 307
 308        return wil->pmc.last_cmd_status;
 309}
 310
 311/* Read from required position up to the end of current descriptor,
 312 * depends on descriptor size configured during alloc request.
 313 */
 314ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
 315                     loff_t *f_pos)
 316{
 317        struct wil6210_priv *wil = filp->private_data;
 318        struct pmc_ctx *pmc = &wil->pmc;
 319        size_t retval = 0;
 320        unsigned long long idx;
 321        loff_t offset;
 322        size_t pmc_size;
 323
 324        mutex_lock(&pmc->lock);
 325
 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);
 330                return -EPERM;
 331        }
 332
 333        pmc_size = pmc->descriptor_size * pmc->num_descriptors;
 334
 335        wil_dbg_misc(wil,
 336                     "pmc_read: size %u, pos %lld\n",
 337                     (u32)count, *f_pos);
 338
 339        pmc->last_cmd_status = 0;
 340
 341        idx = *f_pos;
 342        do_div(idx, pmc->descriptor_size);
 343        offset = *f_pos - (idx * pmc->descriptor_size);
 344
 345        if (*f_pos >= pmc_size) {
 346                wil_dbg_misc(wil,
 347                             "pmc_read: reached end of pmc buf: %lld >= %u\n",
 348                             *f_pos, (u32)pmc_size);
 349                pmc->last_cmd_status = -ERANGE;
 350                goto out;
 351        }
 352
 353        wil_dbg_misc(wil,
 354                     "pmc_read: read from pos %lld (descriptor %llu, offset %llu) %zu bytes\n",
 355                     *f_pos, idx, offset, count);
 356
 357        /* if no errors, return the copied byte count */
 358        retval = simple_read_from_buffer(buf,
 359                                         count,
 360                                         &offset,
 361                                         pmc->descriptors[idx].va,
 362                                         pmc->descriptor_size);
 363        *f_pos += retval;
 364out:
 365        mutex_unlock(&pmc->lock);
 366
 367        return retval;
 368}
 369
 370loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence)
 371{
 372        loff_t newpos;
 373        struct wil6210_priv *wil = filp->private_data;
 374        struct pmc_ctx *pmc = &wil->pmc;
 375        size_t pmc_size;
 376
 377        mutex_lock(&pmc->lock);
 378
 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);
 383                return -EPERM;
 384        }
 385
 386        pmc_size = pmc->descriptor_size * pmc->num_descriptors;
 387
 388        switch (whence) {
 389        case 0: /* SEEK_SET */
 390                newpos = off;
 391                break;
 392
 393        case 1: /* SEEK_CUR */
 394                newpos = filp->f_pos + off;
 395                break;
 396
 397        case 2: /* SEEK_END */
 398                newpos = pmc_size;
 399                break;
 400
 401        default: /* can't happen */
 402                newpos = -EINVAL;
 403                goto out;
 404        }
 405
 406        if (newpos < 0) {
 407                newpos = -EINVAL;
 408                goto out;
 409        }
 410        if (newpos > pmc_size)
 411                newpos = pmc_size;
 412
 413        filp->f_pos = newpos;
 414
 415out:
 416        mutex_unlock(&pmc->lock);
 417
 418        return newpos;
 419}
 420
 421int wil_pmcring_read(struct seq_file *s, void *data)
 422{
 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;
 427
 428        mutex_lock(&pmc->lock);
 429
 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);
 434                return -EPERM;
 435        }
 436
 437        wil_dbg_misc(wil, "pmcring_read: size %zu\n", pmc_ring_size);
 438
 439        seq_write(s, pmc->pring_va, pmc_ring_size);
 440
 441        mutex_unlock(&pmc->lock);
 442
 443        return 0;
 444}
 445