Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright 2008-2010 Cisco Systems, Inc.  All rights reserved.
0004  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
0005  */
0006 
0007 #include <linux/kernel.h>
0008 #include <linux/errno.h>
0009 #include <linux/types.h>
0010 #include <linux/pci.h>
0011 #include <linux/delay.h>
0012 #include <linux/slab.h>
0013 
0014 #include "vnic_dev.h"
0015 #include "vnic_rq.h"
0016 #include "enic.h"
0017 
0018 static int vnic_rq_alloc_bufs(struct vnic_rq *rq)
0019 {
0020     struct vnic_rq_buf *buf;
0021     unsigned int i, j, count = rq->ring.desc_count;
0022     unsigned int blks = VNIC_RQ_BUF_BLKS_NEEDED(count);
0023 
0024     for (i = 0; i < blks; i++) {
0025         rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ(count), GFP_KERNEL);
0026         if (!rq->bufs[i])
0027             return -ENOMEM;
0028     }
0029 
0030     for (i = 0; i < blks; i++) {
0031         buf = rq->bufs[i];
0032         for (j = 0; j < VNIC_RQ_BUF_BLK_ENTRIES(count); j++) {
0033             buf->index = i * VNIC_RQ_BUF_BLK_ENTRIES(count) + j;
0034             buf->desc = (u8 *)rq->ring.descs +
0035                 rq->ring.desc_size * buf->index;
0036             if (buf->index + 1 == count) {
0037                 buf->next = rq->bufs[0];
0038                 break;
0039             } else if (j + 1 == VNIC_RQ_BUF_BLK_ENTRIES(count)) {
0040                 buf->next = rq->bufs[i + 1];
0041             } else {
0042                 buf->next = buf + 1;
0043                 buf++;
0044             }
0045         }
0046     }
0047 
0048     rq->to_use = rq->to_clean = rq->bufs[0];
0049 
0050     return 0;
0051 }
0052 
0053 void vnic_rq_free(struct vnic_rq *rq)
0054 {
0055     struct vnic_dev *vdev;
0056     unsigned int i;
0057 
0058     vdev = rq->vdev;
0059 
0060     vnic_dev_free_desc_ring(vdev, &rq->ring);
0061 
0062     for (i = 0; i < VNIC_RQ_BUF_BLKS_MAX; i++) {
0063         if (rq->bufs[i]) {
0064             kfree(rq->bufs[i]);
0065             rq->bufs[i] = NULL;
0066         }
0067     }
0068 
0069     rq->ctrl = NULL;
0070 }
0071 
0072 int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
0073     unsigned int desc_count, unsigned int desc_size)
0074 {
0075     int err;
0076 
0077     rq->index = index;
0078     rq->vdev = vdev;
0079 
0080     rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_RQ, index);
0081     if (!rq->ctrl) {
0082         vdev_err(vdev, "Failed to hook RQ[%d] resource\n", index);
0083         return -EINVAL;
0084     }
0085 
0086     vnic_rq_disable(rq);
0087 
0088     err = vnic_dev_alloc_desc_ring(vdev, &rq->ring, desc_count, desc_size);
0089     if (err)
0090         return err;
0091 
0092     err = vnic_rq_alloc_bufs(rq);
0093     if (err) {
0094         vnic_rq_free(rq);
0095         return err;
0096     }
0097 
0098     return 0;
0099 }
0100 
0101 static void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
0102     unsigned int fetch_index, unsigned int posted_index,
0103     unsigned int error_interrupt_enable,
0104     unsigned int error_interrupt_offset)
0105 {
0106     u64 paddr;
0107     unsigned int count = rq->ring.desc_count;
0108 
0109     paddr = (u64)rq->ring.base_addr | VNIC_PADDR_TARGET;
0110     writeq(paddr, &rq->ctrl->ring_base);
0111     iowrite32(count, &rq->ctrl->ring_size);
0112     iowrite32(cq_index, &rq->ctrl->cq_index);
0113     iowrite32(error_interrupt_enable, &rq->ctrl->error_interrupt_enable);
0114     iowrite32(error_interrupt_offset, &rq->ctrl->error_interrupt_offset);
0115     iowrite32(0, &rq->ctrl->dropped_packet_count);
0116     iowrite32(0, &rq->ctrl->error_status);
0117     iowrite32(fetch_index, &rq->ctrl->fetch_index);
0118     iowrite32(posted_index, &rq->ctrl->posted_index);
0119 
0120     rq->to_use = rq->to_clean =
0121         &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES(count)]
0122             [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES(count)];
0123 }
0124 
0125 void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
0126     unsigned int error_interrupt_enable,
0127     unsigned int error_interrupt_offset)
0128 {
0129     vnic_rq_init_start(rq, cq_index, 0, 0, error_interrupt_enable,
0130                error_interrupt_offset);
0131 }
0132 
0133 unsigned int vnic_rq_error_status(struct vnic_rq *rq)
0134 {
0135     return ioread32(&rq->ctrl->error_status);
0136 }
0137 
0138 void vnic_rq_enable(struct vnic_rq *rq)
0139 {
0140     iowrite32(1, &rq->ctrl->enable);
0141 }
0142 
0143 int vnic_rq_disable(struct vnic_rq *rq)
0144 {
0145     unsigned int wait;
0146     struct vnic_dev *vdev = rq->vdev;
0147     int i;
0148 
0149     /* Due to a race condition with clearing RQ "mini-cache" in hw, we need
0150      * to disable the RQ twice to guarantee that stale descriptors are not
0151      * used when this RQ is re-enabled.
0152      */
0153     for (i = 0; i < 2; i++) {
0154         iowrite32(0, &rq->ctrl->enable);
0155 
0156         /* Wait for HW to ACK disable request */
0157         for (wait = 20000; wait > 0; wait--)
0158             if (!ioread32(&rq->ctrl->running))
0159                 break;
0160         if (!wait) {
0161             vdev_neterr(vdev, "Failed to disable RQ[%d]\n",
0162                     rq->index);
0163 
0164             return -ETIMEDOUT;
0165         }
0166     }
0167 
0168     return 0;
0169 }
0170 
0171 void vnic_rq_clean(struct vnic_rq *rq,
0172     void (*buf_clean)(struct vnic_rq *rq, struct vnic_rq_buf *buf))
0173 {
0174     struct vnic_rq_buf *buf;
0175     u32 fetch_index;
0176     unsigned int count = rq->ring.desc_count;
0177     int i;
0178 
0179     buf = rq->to_clean;
0180 
0181     for (i = 0; i < rq->ring.desc_count; i++) {
0182         (*buf_clean)(rq, buf);
0183         buf = buf->next;
0184     }
0185     rq->ring.desc_avail = rq->ring.desc_count - 1;
0186 
0187     /* Use current fetch_index as the ring starting point */
0188     fetch_index = ioread32(&rq->ctrl->fetch_index);
0189 
0190     if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone  */
0191         /* Hardware surprise removal: reset fetch_index */
0192         fetch_index = 0;
0193     }
0194     rq->to_use = rq->to_clean =
0195         &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES(count)]
0196             [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES(count)];
0197     iowrite32(fetch_index, &rq->ctrl->posted_index);
0198 
0199     /* Anytime we write fetch_index, we need to re-write 0 to rq->enable
0200      * to re-sync internal VIC state.
0201      */
0202     iowrite32(0, &rq->ctrl->enable);
0203 
0204     vnic_dev_clear_desc_ring(&rq->ring);
0205 }