172 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright 2008 Cisco Systems, Inc. All rights reserved.4 * Copyright 2007 Nuova Systems, Inc. All rights reserved.5 */6#ifndef _VNIC_WQ_H_7#define _VNIC_WQ_H_8 9#include <linux/pci.h>10#include "vnic_dev.h"11#include "vnic_cq.h"12 13/*14 * These defines avoid symbol clash between fnic and enic (Cisco 10G Eth15 * Driver) when both are built with CONFIG options =y16 */17#define vnic_wq_desc_avail fnic_wq_desc_avail18#define vnic_wq_desc_used fnic_wq_desc_used19#define vnic_wq_next_desc fni_cwq_next_desc20#define vnic_wq_post fnic_wq_post21#define vnic_wq_service fnic_wq_service22#define vnic_wq_free fnic_wq_free23#define vnic_wq_alloc fnic_wq_alloc24#define vnic_wq_devcmd2_alloc fnic_wq_devcmd2_alloc25#define vnic_wq_init_start fnic_wq_init_start26#define vnic_wq_init fnic_wq_init27#define vnic_wq_error_status fnic_wq_error_status28#define vnic_wq_enable fnic_wq_enable29#define vnic_wq_disable fnic_wq_disable30#define vnic_wq_clean fnic_wq_clean31 32/* Work queue control */33struct vnic_wq_ctrl {34 u64 ring_base; /* 0x00 */35 u32 ring_size; /* 0x08 */36 u32 pad0;37 u32 posted_index; /* 0x10 */38 u32 pad1;39 u32 cq_index; /* 0x18 */40 u32 pad2;41 u32 enable; /* 0x20 */42 u32 pad3;43 u32 running; /* 0x28 */44 u32 pad4;45 u32 fetch_index; /* 0x30 */46 u32 pad5;47 u32 dca_value; /* 0x38 */48 u32 pad6;49 u32 error_interrupt_enable; /* 0x40 */50 u32 pad7;51 u32 error_interrupt_offset; /* 0x48 */52 u32 pad8;53 u32 error_status; /* 0x50 */54 u32 pad9;55};56 57struct vnic_wq_buf {58 struct vnic_wq_buf *next;59 dma_addr_t dma_addr;60 void *os_buf;61 unsigned int len;62 unsigned int index;63 int sop;64 void *desc;65};66 67/* Break the vnic_wq_buf allocations into blocks of 64 entries */68#define VNIC_WQ_BUF_BLK_ENTRIES 6469#define VNIC_WQ_BUF_BLK_SZ \70 (VNIC_WQ_BUF_BLK_ENTRIES * sizeof(struct vnic_wq_buf))71#define VNIC_WQ_BUF_BLKS_NEEDED(entries) \72 DIV_ROUND_UP(entries, VNIC_WQ_BUF_BLK_ENTRIES)73#define VNIC_WQ_BUF_BLKS_MAX VNIC_WQ_BUF_BLKS_NEEDED(4096)74 75struct vnic_wq {76 unsigned int index;77 struct vnic_dev *vdev;78 struct vnic_wq_ctrl __iomem *ctrl; /* memory-mapped */79 struct vnic_dev_ring ring;80 struct vnic_wq_buf *bufs[VNIC_WQ_BUF_BLKS_MAX];81 struct vnic_wq_buf *to_use;82 struct vnic_wq_buf *to_clean;83 unsigned int pkts_outstanding;84};85 86static inline unsigned int vnic_wq_desc_avail(struct vnic_wq *wq)87{88 /* how many does SW own? */89 return wq->ring.desc_avail;90}91 92static inline unsigned int vnic_wq_desc_used(struct vnic_wq *wq)93{94 /* how many does HW own? */95 return wq->ring.desc_count - wq->ring.desc_avail - 1;96}97 98static inline void *vnic_wq_next_desc(struct vnic_wq *wq)99{100 return wq->to_use->desc;101}102 103static inline void vnic_wq_post(struct vnic_wq *wq,104 void *os_buf, dma_addr_t dma_addr,105 unsigned int len, int sop, int eop)106{107 struct vnic_wq_buf *buf = wq->to_use;108 109 buf->sop = sop;110 buf->os_buf = eop ? os_buf : NULL;111 buf->dma_addr = dma_addr;112 buf->len = len;113 114 buf = buf->next;115 if (eop) {116 /* Adding write memory barrier prevents compiler and/or CPU117 * reordering, thus avoiding descriptor posting before118 * descriptor is initialized. Otherwise, hardware can read119 * stale descriptor fields.120 */121 wmb();122 iowrite32(buf->index, &wq->ctrl->posted_index);123 }124 wq->to_use = buf;125 126 wq->ring.desc_avail--;127}128 129static inline void vnic_wq_service(struct vnic_wq *wq,130 struct cq_desc *cq_desc, u16 completed_index,131 void (*buf_service)(struct vnic_wq *wq,132 struct cq_desc *cq_desc, struct vnic_wq_buf *buf, void *opaque),133 void *opaque)134{135 struct vnic_wq_buf *buf;136 137 buf = wq->to_clean;138 while (1) {139 140 (*buf_service)(wq, cq_desc, buf, opaque);141 142 wq->ring.desc_avail++;143 144 wq->to_clean = buf->next;145 146 if (buf->index == completed_index)147 break;148 149 buf = wq->to_clean;150 }151}152 153void vnic_wq_free(struct vnic_wq *wq);154int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,155 unsigned int desc_count, unsigned int desc_size);156int vnic_wq_devcmd2_alloc(struct vnic_dev *vdev, struct vnic_wq *wq,157 unsigned int desc_count, unsigned int desc_size);158void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,159 unsigned int fetch_index, unsigned int posted_index,160 unsigned int error_interrupt_enable,161 unsigned int error_interrupt_offset);162void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,163 unsigned int error_interrupt_enable,164 unsigned int error_interrupt_offset);165unsigned int vnic_wq_error_status(struct vnic_wq *wq);166void vnic_wq_enable(struct vnic_wq *wq);167int vnic_wq_disable(struct vnic_wq *wq);168void vnic_wq_clean(struct vnic_wq *wq,169 void (*buf_clean)(struct vnic_wq *wq, struct vnic_wq_buf *buf));170 171#endif /* _VNIC_WQ_H_ */172