157 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/* Copyright 2014 Cisco Systems, Inc. All rights reserved. */3 4#ifndef _VNIC_WQ_H_5#define _VNIC_WQ_H_6 7#include <linux/pci.h>8#include "vnic_dev.h"9#include "vnic_cq.h"10 11/* Work queue control */12struct vnic_wq_ctrl {13 u64 ring_base; /* 0x00 */14 u32 ring_size; /* 0x08 */15 u32 pad0;16 u32 posted_index; /* 0x10 */17 u32 pad1;18 u32 cq_index; /* 0x18 */19 u32 pad2;20 u32 enable; /* 0x20 */21 u32 pad3;22 u32 running; /* 0x28 */23 u32 pad4;24 u32 fetch_index; /* 0x30 */25 u32 pad5;26 u32 dca_value; /* 0x38 */27 u32 pad6;28 u32 error_interrupt_enable; /* 0x40 */29 u32 pad7;30 u32 error_interrupt_offset; /* 0x48 */31 u32 pad8;32 u32 error_status; /* 0x50 */33 u32 pad9;34};35 36struct vnic_wq_buf {37 struct vnic_wq_buf *next;38 dma_addr_t dma_addr;39 void *os_buf;40 unsigned int len;41 unsigned int index;42 int sop;43 void *desc;44};45 46/* Break the vnic_wq_buf allocations into blocks of 64 entries */47#define VNIC_WQ_BUF_MIN_BLK_ENTRIES 3248#define VNIC_WQ_BUF_DFLT_BLK_ENTRIES 6449#define VNIC_WQ_BUF_BLK_ENTRIES(entries) \50 ((unsigned int)(entries < VNIC_WQ_BUF_DFLT_BLK_ENTRIES) ? \51 VNIC_WQ_BUF_MIN_BLK_ENTRIES : VNIC_WQ_BUF_DFLT_BLK_ENTRIES)52#define VNIC_WQ_BUF_BLK_SZ \53 (VNIC_WQ_BUF_DFLT_BLK_ENTRIES * sizeof(struct vnic_wq_buf))54#define VNIC_WQ_BUF_BLKS_NEEDED(entries) \55 DIV_ROUND_UP(entries, VNIC_WQ_BUF_DFLT_BLK_ENTRIES)56#define VNIC_WQ_BUF_BLKS_NEEDED(entries) \57 DIV_ROUND_UP(entries, VNIC_WQ_BUF_DFLT_BLK_ENTRIES)58#define VNIC_WQ_BUF_BLKS_MAX VNIC_WQ_BUF_BLKS_NEEDED(4096)59 60struct vnic_wq {61 unsigned int index;62 struct vnic_dev *vdev;63 struct vnic_wq_ctrl __iomem *ctrl; /* memory-mapped */64 struct vnic_dev_ring ring;65 struct vnic_wq_buf *bufs[VNIC_WQ_BUF_BLKS_MAX];66 struct vnic_wq_buf *to_use;67 struct vnic_wq_buf *to_clean;68 unsigned int pkts_outstanding;69};70 71static inline unsigned int svnic_wq_desc_avail(struct vnic_wq *wq)72{73 /* how many does SW own? */74 return wq->ring.desc_avail;75}76 77static inline unsigned int svnic_wq_desc_used(struct vnic_wq *wq)78{79 /* how many does HW own? */80 return wq->ring.desc_count - wq->ring.desc_avail - 1;81}82 83static inline void *svnic_wq_next_desc(struct vnic_wq *wq)84{85 return wq->to_use->desc;86}87 88static inline void svnic_wq_post(struct vnic_wq *wq,89 void *os_buf, dma_addr_t dma_addr,90 unsigned int len, int sop, int eop)91{92 struct vnic_wq_buf *buf = wq->to_use;93 94 buf->sop = sop;95 buf->os_buf = eop ? os_buf : NULL;96 buf->dma_addr = dma_addr;97 buf->len = len;98 99 buf = buf->next;100 if (eop) {101 /* Adding write memory barrier prevents compiler and/or CPU102 * reordering, thus avoiding descriptor posting before103 * descriptor is initialized. Otherwise, hardware can read104 * stale descriptor fields.105 */106 wmb();107 iowrite32(buf->index, &wq->ctrl->posted_index);108 }109 wq->to_use = buf;110 111 wq->ring.desc_avail--;112}113 114static inline void svnic_wq_service(struct vnic_wq *wq,115 struct cq_desc *cq_desc, u16 completed_index,116 void (*buf_service)(struct vnic_wq *wq,117 struct cq_desc *cq_desc, struct vnic_wq_buf *buf, void *opaque),118 void *opaque)119{120 struct vnic_wq_buf *buf;121 122 buf = wq->to_clean;123 while (1) {124 125 (*buf_service)(wq, cq_desc, buf, opaque);126 127 wq->ring.desc_avail++;128 129 wq->to_clean = buf->next;130 131 if (buf->index == completed_index)132 break;133 134 buf = wq->to_clean;135 }136}137 138void svnic_wq_free(struct vnic_wq *wq);139int svnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq,140 unsigned int index, unsigned int desc_count, unsigned int desc_size);141int vnic_wq_devcmd2_alloc(struct vnic_dev *vdev, struct vnic_wq *wq,142 unsigned int desc_count, unsigned int desc_size);143void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,144 unsigned int fetch_index, unsigned int post_index,145 unsigned int error_interrupt_enable,146 unsigned int error_interrupt_offset);147 148void svnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,149 unsigned int error_interrupt_enable,150 unsigned int error_interrupt_offset);151unsigned int svnic_wq_error_status(struct vnic_wq *wq);152void svnic_wq_enable(struct vnic_wq *wq);153int svnic_wq_disable(struct vnic_wq *wq);154void svnic_wq_clean(struct vnic_wq *wq,155 void (*buf_clean)(struct vnic_wq *wq, struct vnic_wq_buf *buf));156#endif /* _VNIC_WQ_H_ */157