summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_buf.h
blob: dd435cca82145fa01d2ba677b1bc13d2e63be171 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/* Copyright © 2003-2011 Emulex. All rights reserved.  */

/*
 * Header file defining the driver buffer management interface
 */

#ifndef _OCE_BUF_H_
#define	_OCE_BUF_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/ddidmareq.h>
#include <oce_io.h>
#include <oce_utils.h>

#define	GET_Q_NEXT(_START, _STEP, _END) \
	(((_START) + (_STEP)) < (_END) ? ((_START) + (_STEP)) \
	: (((_START) + (_STEP)) - (_END)))

#define	OCE_MAX_TX_HDL		8
#define	OCE_MAX_TXDMA_COOKIES	18
#define	OCE_TXMAP_ALIGN		1
#define	OCE_TX_MAX_FRAGS	(OCE_MAX_TX_HDL * OCE_MAX_TXDMA_COOKIES)

/* helper structure to access OS addresses */
typedef union  oce_addr_s {
	uint64_t addr64;
	struct {
#ifdef _BIG_ENDIAN
		uint32_t addr_hi;
		uint32_t addr_lo;
#else
		uint32_t addr_lo;
		uint32_t addr_hi;
#endif
	}dw;
}oce_addr64_t;

typedef struct oce_dma_buf_s {
	caddr_t		base;
	uint64_t	addr;
	ddi_acc_handle_t acc_handle;
	ddi_dma_handle_t dma_handle;
	/* size of the memory */
	size_t		size;
	size_t		off;
	size_t		len;
	uint32_t	num_pages;
}oce_dma_buf_t;

#define	DBUF_PA(obj) (((oce_dma_buf_t *)(obj))->addr)
#define	DBUF_VA(obj) (((oce_dma_buf_t *)(obj))->base)
#define	DBUF_DHDL(obj) (((oce_dma_buf_t *)(obj))->dma_handle)
#define	DBUF_AHDL(obj) (((oce_dma_buf_t *)obj))->acc_handle)
#define	DBUF_SYNC(obj, flags)	(void) ddi_dma_sync(DBUF_DHDL(obj), 0,\
			0, (flags))

typedef struct oce_ring_buffer_s {
	uint16_t    cidx; 	/* Get ptr */
	uint16_t    pidx;	/* Put Ptr */
	size_t	item_size;	/* Size */
	size_t  num_items;	/* count */
	uint32_t  num_used;
	oce_dma_buf_t   *dbuf;	/* dma buffer */
}oce_ring_buffer_t;

typedef struct oce_rq_bdesc_s {
	oce_dma_buf_t	*rqb;
	struct oce_rq	*rq;
	oce_addr64_t 	frag_addr;
	mblk_t		*mp;
	frtn_t		fr_rtn;
    uint32_t    ref_cnt;
}oce_rq_bdesc_t;

typedef struct oce_wq_bdesc_s {
	OCE_LIST_NODE_T  link;
	oce_dma_buf_t	*wqb;
	oce_addr64_t 	frag_addr;
} oce_wq_bdesc_t;

typedef struct oce_wq_mdesc_s {
	OCE_LIST_NODE_T  	link;
	ddi_dma_handle_t	dma_handle;
} oce_wq_mdesc_t;

enum entry_type {
	HEADER_WQE = 0x1, /* arbitrary value */
	MAPPED_WQE,
	COPY_WQE,
	DUMMY_WQE
};

typedef struct _oce_handle_s {
    enum entry_type	type;
	void		*hdl; /* opaque handle */
}oce_handle_t;

typedef struct _oce_wqe_desc_s {
	OCE_LIST_NODE_T  link;
	oce_handle_t	hdesc[OCE_MAX_TX_HDL];
	struct oce_nic_frag_wqe frag[OCE_TX_MAX_FRAGS];
	struct oce_wq  *wq;
	mblk_t		*mp;
	uint16_t	wqe_cnt;
	uint16_t	frag_idx;
	uint16_t	frag_cnt;
	uint16_t	nhdl;
}oce_wqe_desc_t;

#pragma pack(1)
/* Always keep it 2 mod 4 */
typedef struct _oce_rq_buf_hdr_s {
	void *datap;
	uint8_t pad[18];
	/* ether_vlan_header_t vhdr; */
} oce_rq_buf_hdr_t;
#pragma pack()

#define	OCE_RQE_BUF_HEADROOM	18
#define	MAX_POOL_NAME		32

#define	RING_NUM_PENDING(ring)	ring->num_used

#define	RING_NUM_FREE(ring)	\
	(uint32_t)(ring->num_items - ring->num_used)

#define	RING_FULL(ring) (ring->num_used == ring->num_items)

#define	RING_EMPTY(ring) (ring->num_used == 0)

#define	RING_GET(ring, n)			\
	ring->cidx = GET_Q_NEXT(ring->cidx, n, ring->num_items)

#define	RING_PUT(ring, n)			\
	ring->pidx = GET_Q_NEXT(ring->pidx, n, ring->num_items)

#define	RING_GET_CONSUMER_ITEM_VA(ring, type) 	\
	(void*)(((type *)DBUF_VA(ring->dbuf)) + ring->cidx)

#define	RING_GET_CONSUMER_ITEM_PA(ring, type)		\
	(uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->cidx)

#define	RING_GET_PRODUCER_ITEM_VA(ring, type)		\
	(void *)(((type *)DBUF_VA(ring->dbuf)) + ring->pidx)

#define	RING_GET_PRODUCER_ITEM_PA(ring, type)		\
	(uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->pidx)

/* Rq cache */
int oce_rqb_cache_create(struct oce_rq *rq, size_t buf_size);
void oce_rqb_cache_destroy(struct oce_rq *rq);

/* Wq Cache */
int oce_wqe_desc_ctor(void *buf, void *arg, int kmflags);
void oce_wqe_desc_dtor(void *buf, void *arg);

int oce_wqb_cache_create(struct oce_wq *wq, size_t buf_size);
void oce_wqb_cache_destroy(struct oce_wq *wq);

void oce_wqm_cache_destroy(struct oce_wq *wq);
int oce_wqm_cache_create(struct oce_wq *wq);

void oce_page_list(oce_dma_buf_t *dbuf,
    struct phys_addr *pa_list, int list_size);


#ifdef __cplusplus
}
#endif

#endif /* _OCE_BUF_H_ */