190792Sgshapiro/**************************************************************************
290792Sgshapiro
390792SgshapiroCopyright (c) 2007, 2008 Chelsio Inc.
490792SgshapiroAll rights reserved.
590792Sgshapiro
690792SgshapiroRedistribution and use in source and binary forms, with or without
790792Sgshapiromodification, are permitted provided that the following conditions are met:
890792Sgshapiro
990792Sgshapiro 1. Redistributions of source code must retain the above copyright notice,
1090792Sgshapiro    this list of conditions and the following disclaimer.
1190792Sgshapiro
1290792Sgshapiro 2. Neither the name of the Chelsio Corporation nor the names of its
1390792Sgshapiro    contributors may be used to endorse or promote products derived from
1490792Sgshapiro    this software without specific prior written permission.
1590792Sgshapiro
1690792SgshapiroTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1790792SgshapiroAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1890792SgshapiroIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1990792SgshapiroARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2090792SgshapiroLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2190792SgshapiroCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2290792SgshapiroSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2390792SgshapiroINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2490792SgshapiroCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2590792SgshapiroARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2690792SgshapiroPOSSIBILITY OF SUCH DAMAGE.
2790792Sgshapiro
2890792Sgshapiro$FreeBSD: releng/11.0/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_hal.h 237263 2012-06-19 07:34:13Z np $
2990792Sgshapiro
3090792Sgshapiro***************************************************************************/
3190792Sgshapiro#ifndef  __CXIO_HAL_H__
3290792Sgshapiro#define  __CXIO_HAL_H__
3390792Sgshapiro#include <sys/condvar.h>
3490792Sgshapiro#include <sys/ktr.h>
3590792Sgshapiro
3690792Sgshapiro#define T3_CTRL_QP_ID    FW_RI_SGEEC_START
3790792Sgshapiro#define T3_CTL_QP_TID	 FW_RI_TID_START
3890792Sgshapiro#define T3_CTRL_QP_SIZE_LOG2  8
3990792Sgshapiro#define T3_CTRL_CQ_ID    0
4090792Sgshapiro
4190792Sgshapiro/* TBD */
4290792Sgshapiro#define T3_MAX_NUM_RI (1<<15)
4390792Sgshapiro#define T3_MAX_NUM_QP (1<<15)
4490792Sgshapiro#define T3_MAX_NUM_CQ (1<<15)
4590792Sgshapiro#define T3_MAX_NUM_PD (1<<15)
4690792Sgshapiro#define T3_MAX_PBL_SIZE 256
4790792Sgshapiro#define T3_MAX_RQ_SIZE 1024
4890792Sgshapiro#define T3_MAX_QP_DEPTH (T3_MAX_RQ_SIZE-1)
4990792Sgshapiro#define T3_MAX_CQ_DEPTH 65536
5090792Sgshapiro#define T3_MAX_NUM_STAG (1<<15)
5190792Sgshapiro#define T3_MAX_MR_SIZE 0x100000000ULL
5290792Sgshapiro#define T3_PAGESIZE_MASK 0xffff000  /* 4KB-128MB */
5390792Sgshapiro
5490792Sgshapiro#define T3_STAG_UNSET 0xffffffff
5590792Sgshapiro
5690792Sgshapiro#define T3_MAX_DEV_NAME_LEN 32
5790792Sgshapiro
5890792Sgshapirostruct cxio_hal_ctrl_qp {
5990792Sgshapiro	u32 wptr;
6090792Sgshapiro	u32 rptr;
6190792Sgshapiro	struct mtx lock;	/* for the wtpr, can sleep */
6290792Sgshapiro	union t3_wr *workq;	/* the work request queue */
6390792Sgshapiro	bus_addr_t dma_addr;	/* pci bus address of the workq */
6490792Sgshapiro	void *doorbell;
6590792Sgshapiro};
6690792Sgshapiro
6790792Sgshapirostruct cxio_hal_resource {
6890792Sgshapiro	struct buf_ring *tpt_fifo;
6990792Sgshapiro	struct mtx tpt_fifo_lock;
7090792Sgshapiro	struct buf_ring *qpid_fifo;
7190792Sgshapiro	struct mtx qpid_fifo_lock;
7290792Sgshapiro	struct buf_ring *cqid_fifo;
7390792Sgshapiro	struct mtx cqid_fifo_lock;
7490792Sgshapiro	struct buf_ring *pdid_fifo;
7590792Sgshapiro	struct mtx pdid_fifo_lock;
7690792Sgshapiro};
7790792Sgshapiro
7890792Sgshapirostruct cxio_qpid {
7990792Sgshapiro	TAILQ_ENTRY(cxio_qpid) entry;
8090792Sgshapiro	u32 qpid;
8190792Sgshapiro};
8290792Sgshapiro
8390792Sgshapirostruct cxio_ucontext {
8490792Sgshapiro	TAILQ_HEAD(, cxio_qpid) qpids;
8590792Sgshapiro	struct mtx lock;
86};
87
88struct 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
103static __inline int
104cxio_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
109typedef 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
122struct 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
129enum 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
136int cxio_rdev_open(struct cxio_rdev *rdev);
137void cxio_rdev_close(struct cxio_rdev *rdev);
138int cxio_hal_cq_op(struct cxio_rdev *rdev, struct t3_cq *cq,
139		   enum t3_cq_opcode op, u32 credit);
140int cxio_create_cq(struct cxio_rdev *rdev, struct t3_cq *cq, int kernel);
141int cxio_destroy_cq(struct cxio_rdev *rdev, struct t3_cq *cq);
142void cxio_release_ucontext(struct cxio_rdev *rdev, struct cxio_ucontext *uctx);
143void cxio_init_ucontext(struct cxio_rdev *rdev, struct cxio_ucontext *uctx);
144int cxio_create_qp(struct cxio_rdev *rdev, u32 kernel_domain, struct t3_wq *wq,
145		   struct cxio_ucontext *uctx);
146int cxio_destroy_qp(struct cxio_rdev *rdev, struct t3_wq *wq,
147		    struct cxio_ucontext *uctx);
148int cxio_peek_cq(struct t3_wq *wr, struct t3_cq *cq, int opcode);
149int cxio_write_pbl(struct cxio_rdev *rdev_p, __be64 *pbl,
150		   u32 pbl_addr, u32 pbl_size);
151int 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);
154int 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);
157int cxio_dereg_mem(struct cxio_rdev *rdev, u32 stag, u32 pbl_size,
158		   u32 pbl_addr);
159int cxio_allocate_window(struct cxio_rdev *rdev, u32 * stag, u32 pdid);
160int cxio_deallocate_window(struct cxio_rdev *rdev, u32 stag);
161int cxio_rdma_init(struct cxio_rdev *rdev, struct t3_rdma_init_attr *attr,
162    struct socket *so);
163u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp);
164void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid);
165int cxio_hal_init(struct adapter *);
166void cxio_hal_uninit(struct adapter *);
167void cxio_hal_exit(void);
168int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count);
169int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count);
170void cxio_count_rcqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
171void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
172void cxio_flush_hw_cq(struct t3_cq *cq);
173int 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
179void cxio_dump_tpt(struct cxio_rdev *rev, u32 stag);
180void cxio_dump_pbl(struct cxio_rdev *rev, u32 pbl_addr, uint32_t len, u8 shift);
181void cxio_dump_wqe(union t3_wr *wqe);
182void cxio_dump_wce(struct t3_cqe *wce);
183void cxio_dump_rqt(struct cxio_rdev *rdev, u32 hwtid, int nents);
184void 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>
190struct gen_pool {
191	blist_t  	gen_list;
192	daddr_t  	gen_base;
193	int      	gen_chunk_shift;
194	struct mtx 	gen_lock;
195};
196
197static __inline struct gen_pool *
198gen_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
220static __inline unsigned long
221gen_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
237static __inline void
238gen_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
250static __inline void
251gen_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