1 /**************************************************************************
2 
3 Copyright (c) 2007, 2008 Chelsio Inc.
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9  1. Redistributions of source code must retain the above copyright notice,
10     this list of conditions and the following disclaimer.
11 
12  2. Neither the name of the Chelsio Corporation nor the names of its
13     contributors may be used to endorse or promote products derived from
14     this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 POSSIBILITY OF SUCH DAMAGE.
27 
28 $FreeBSD: stable/9/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_hal.h 237920 2012-07-01 12:00:36Z np $
29 
30 ***************************************************************************/
31 #ifndef  __CXIO_HAL_H__
32 #define  __CXIO_HAL_H__
33 #include <sys/condvar.h>
34 #include <sys/ktr.h>
35 
36 #define T3_CTRL_QP_ID    FW_RI_SGEEC_START
37 #define T3_CTL_QP_TID	 FW_RI_TID_START
38 #define T3_CTRL_QP_SIZE_LOG2  8
39 #define T3_CTRL_CQ_ID    0
40 
41 /* TBD */
42 #define T3_MAX_NUM_RI (1<<15)
43 #define T3_MAX_NUM_QP (1<<15)
44 #define T3_MAX_NUM_CQ (1<<15)
45 #define T3_MAX_NUM_PD (1<<15)
46 #define T3_MAX_PBL_SIZE 256
47 #define T3_MAX_RQ_SIZE 1024
48 #define T3_MAX_QP_DEPTH (T3_MAX_RQ_SIZE-1)
49 #define T3_MAX_CQ_DEPTH 65536
50 #define T3_MAX_NUM_STAG (1<<15)
51 #define T3_MAX_MR_SIZE 0x100000000ULL
52 #define T3_PAGESIZE_MASK 0xffff000  /* 4KB-128MB */
53 
54 #define T3_STAG_UNSET 0xffffffff
55 
56 #define T3_MAX_DEV_NAME_LEN 32
57 
58 struct cxio_hal_ctrl_qp {
59 	u32 wptr;
60 	u32 rptr;
61 	struct mtx lock;	/* for the wtpr, can sleep */
62 	union t3_wr *workq;	/* the work request queue */
63 	bus_addr_t dma_addr;	/* pci bus address of the workq */
64 	void *doorbell;
65 };
66 
67 struct cxio_hal_resource {
68 	struct buf_ring *tpt_fifo;
69 	struct mtx tpt_fifo_lock;
70 	struct buf_ring *qpid_fifo;
71 	struct mtx qpid_fifo_lock;
72 	struct buf_ring *cqid_fifo;
73 	struct mtx cqid_fifo_lock;
74 	struct buf_ring *pdid_fifo;
75 	struct mtx pdid_fifo_lock;
76 };
77 
78 struct cxio_qpid {
79 	TAILQ_ENTRY(cxio_qpid) entry;
80 	u32 qpid;
81 };
82 
83 struct cxio_ucontext {
84 	TAILQ_HEAD(, cxio_qpid) qpids;
85 	struct mtx lock;
86 };
87 
88 struct cxio_rdev {
89 	struct adapter *adap;
90 	struct rdma_info rnic_info;
91 	struct cxio_hal_resource *rscp;
92 	struct cxio_hal_ctrl_qp ctrl_qp;
93 	unsigned long qpshift;
94 	u32 qpnr;
95 	u32 qpmask;
96 	struct cxio_ucontext uctx;
97 	struct gen_pool *pbl_pool;
98 	struct gen_pool *rqt_pool;
99 	struct ifnet *ifp;
100 	TAILQ_ENTRY(cxio_rdev) entry;
101 };
102 
103 static __inline int
cxio_num_stags(struct cxio_rdev * rdev_p)104 cxio_num_stags(struct cxio_rdev *rdev_p)
105 {
106 	return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5));
107 }
108 
109 typedef void (*cxio_hal_ev_callback_func_t) (struct cxio_rdev * rdev_p,
110 					     struct mbuf * m);
111 
112 #define RSPQ_CQID(rsp) (be32toh(rsp->cq_ptrid) & 0xffff)
113 #define RSPQ_CQPTR(rsp) ((be32toh(rsp->cq_ptrid) >> 16) & 0xffff)
114 #define RSPQ_GENBIT(rsp) ((be32toh(rsp->flags) >> 16) & 1)
115 #define RSPQ_OVERFLOW(rsp) ((be32toh(rsp->flags) >> 17) & 1)
116 #define RSPQ_AN(rsp) ((be32toh(rsp->flags) >> 18) & 1)
117 #define RSPQ_SE(rsp) ((be32toh(rsp->flags) >> 19) & 1)
118 #define RSPQ_NOTIFY(rsp) ((be32toh(rsp->flags) >> 20) & 1)
119 #define RSPQ_CQBRANCH(rsp) ((be32toh(rsp->flags) >> 21) & 1)
120 #define RSPQ_CREDIT_THRESH(rsp) ((be32toh(rsp->flags) >> 22) & 1)
121 
122 struct respQ_msg_t {
123 	__be32 flags;		/* flit 0 */
124 	__be32 cq_ptrid;
125 	__be64 rsvd;		/* flit 1 */
126 	struct t3_cqe cqe;	/* flits 2-3 */
127 };
128 
129 enum t3_cq_opcode {
130 	CQ_ARM_AN = 0x2,
131 	CQ_ARM_SE = 0x6,
132 	CQ_FORCE_AN = 0x3,
133 	CQ_CREDIT_UPDATE = 0x7
134 };
135 
136 int cxio_rdev_open(struct cxio_rdev *rdev);
137 void cxio_rdev_close(struct cxio_rdev *rdev);
138 int cxio_hal_cq_op(struct cxio_rdev *rdev, struct t3_cq *cq,
139 		   enum t3_cq_opcode op, u32 credit);
140 int cxio_create_cq(struct cxio_rdev *rdev, struct t3_cq *cq, int kernel);
141 int cxio_destroy_cq(struct cxio_rdev *rdev, struct t3_cq *cq);
142 void cxio_release_ucontext(struct cxio_rdev *rdev, struct cxio_ucontext *uctx);
143 void cxio_init_ucontext(struct cxio_rdev *rdev, struct cxio_ucontext *uctx);
144 int cxio_create_qp(struct cxio_rdev *rdev, u32 kernel_domain, struct t3_wq *wq,
145 		   struct cxio_ucontext *uctx);
146 int cxio_destroy_qp(struct cxio_rdev *rdev, struct t3_wq *wq,
147 		    struct cxio_ucontext *uctx);
148 int cxio_peek_cq(struct t3_wq *wr, struct t3_cq *cq, int opcode);
149 int cxio_write_pbl(struct cxio_rdev *rdev_p, __be64 *pbl,
150 		   u32 pbl_addr, u32 pbl_size);
151 int cxio_register_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid,
152 			   enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
153 			   u8 page_size, u32 pbl_size, u32 pbl_addr);
154 int cxio_reregister_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid,
155 			   enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
156 			   u8 page_size, u32 pbl_size, u32 pbl_addr);
157 int cxio_dereg_mem(struct cxio_rdev *rdev, u32 stag, u32 pbl_size,
158 		   u32 pbl_addr);
159 int cxio_allocate_window(struct cxio_rdev *rdev, u32 * stag, u32 pdid);
160 int cxio_deallocate_window(struct cxio_rdev *rdev, u32 stag);
161 int cxio_rdma_init(struct cxio_rdev *rdev, struct t3_rdma_init_attr *attr,
162     struct socket *so);
163 u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp);
164 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid);
165 int cxio_hal_init(struct adapter *);
166 void cxio_hal_uninit(struct adapter *);
167 void cxio_hal_exit(void);
168 int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count);
169 int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count);
170 void cxio_count_rcqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
171 void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
172 void cxio_flush_hw_cq(struct t3_cq *cq);
173 int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
174 		     u8 *cqe_flushed, u64 *cookie, u32 *credit);
175 
176 #define MOD "iw_cxgb: "
177 
178 #ifdef INVARIANTS
179 void cxio_dump_tpt(struct cxio_rdev *rev, u32 stag);
180 void cxio_dump_pbl(struct cxio_rdev *rev, u32 pbl_addr, uint32_t len, u8 shift);
181 void cxio_dump_wqe(union t3_wr *wqe);
182 void cxio_dump_wce(struct t3_cqe *wce);
183 void cxio_dump_rqt(struct cxio_rdev *rdev, u32 hwtid, int nents);
184 void cxio_dump_tcb(struct cxio_rdev *rdev, u32 hwtid);
185 #endif
186 
187 #define cxfree(a) free((a), M_DEVBUF);
188 
189 #include <sys/blist.h>
190 struct gen_pool {
191 	blist_t  	gen_list;
192 	daddr_t  	gen_base;
193 	int      	gen_chunk_shift;
194 	struct mtx 	gen_lock;
195 };
196 
197 static __inline struct gen_pool *
gen_pool_create(daddr_t base,u_int chunk_shift,u_int len)198 gen_pool_create(daddr_t base, u_int chunk_shift, u_int len)
199 {
200 	struct gen_pool *gp;
201 
202 	gp = malloc(sizeof(struct gen_pool), M_DEVBUF, M_NOWAIT);
203 	if (gp == NULL)
204 		return (NULL);
205 
206 	memset(gp, 0, sizeof(struct gen_pool));
207 	gp->gen_list = blist_create(len >> chunk_shift, M_NOWAIT);
208 	if (gp->gen_list == NULL) {
209 		free(gp, M_DEVBUF);
210 		return (NULL);
211 	}
212 	blist_free(gp->gen_list, 0, len >> chunk_shift);
213 	gp->gen_base = base;
214 	gp->gen_chunk_shift = chunk_shift;
215 	mtx_init(&gp->gen_lock, "genpool", NULL, MTX_DUPOK|MTX_DEF);
216 
217 	return (gp);
218 }
219 
220 static __inline unsigned long
gen_pool_alloc(struct gen_pool * gp,int size)221 gen_pool_alloc(struct gen_pool *gp, int size)
222 {
223 	int chunks;
224 	daddr_t blkno;
225 
226 	chunks = (size + (1<<gp->gen_chunk_shift) - 1) >> gp->gen_chunk_shift;
227 	mtx_lock(&gp->gen_lock);
228 	blkno = blist_alloc(gp->gen_list, chunks);
229 	mtx_unlock(&gp->gen_lock);
230 
231 	if (blkno == SWAPBLK_NONE)
232 		return (0);
233 
234 	return (gp->gen_base + ((1 << gp->gen_chunk_shift) * blkno));
235 }
236 
237 static __inline void
gen_pool_free(struct gen_pool * gp,daddr_t address,int size)238 gen_pool_free(struct gen_pool *gp, daddr_t address, int size)
239 {
240 	int chunks;
241 	daddr_t blkno;
242 
243 	chunks = (size + (1<<gp->gen_chunk_shift) - 1) >> gp->gen_chunk_shift;
244 	blkno = (address - gp->gen_base) / (1 << gp->gen_chunk_shift);
245 	mtx_lock(&gp->gen_lock);
246 	blist_free(gp->gen_list, blkno, chunks);
247 	mtx_unlock(&gp->gen_lock);
248 }
249 
250 static __inline void
gen_pool_destroy(struct gen_pool * gp)251 gen_pool_destroy(struct gen_pool *gp)
252 {
253 	blist_destroy(gp->gen_list);
254 	free(gp, M_DEVBUF);
255 }
256 
257 #define cxio_wait(ctx, lockp, cond) \
258 ({ \
259 	int __ret = 0; \
260 	mtx_lock(lockp); \
261 	while (!cond) { \
262                 msleep(ctx, lockp, 0, "cxio_wait", hz); \
263                 if (SIGPENDING(curthread)) { \
264 			__ret = ERESTART; \
265                         break; \
266                 } \
267 	} \
268 	mtx_unlock(lockp); \
269 	__ret; \
270 })
271 
272 #define KTR_IW_CXGB KTR_SPARE3
273 
274 #endif
275