]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_hal.h
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / dev / cxgb / ulp / iw_cxgb / iw_cxgb_hal.h
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$
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_NUM_STAG (1<<15)
49
50 #define T3_STAG_UNSET 0xffffffff
51
52 #define T3_MAX_DEV_NAME_LEN 32
53
54 struct cxio_hal_ctrl_qp {
55         u32 wptr;
56         u32 rptr;
57         struct mtx lock;        /* for the wtpr, can sleep */
58 #ifdef notyet
59         DECLARE_PCI_UNMAP_ADDR(mapping)
60 #endif  
61         union t3_wr *workq;     /* the work request queue */
62         bus_addr_t dma_addr;    /* pci bus address of the workq */
63         void /* __iomem */ *doorbell;
64 };
65
66 struct cxio_hal_resource {
67         struct buf_ring *tpt_fifo;
68         struct mtx tpt_fifo_lock;
69         struct buf_ring *qpid_fifo;
70         struct mtx qpid_fifo_lock;
71         struct buf_ring *cqid_fifo;
72         struct mtx cqid_fifo_lock;
73         struct buf_ring *pdid_fifo;
74         struct mtx pdid_fifo_lock;
75 };
76
77 struct cxio_qpid {
78         TAILQ_ENTRY(cxio_qpid) entry;
79         u32 qpid;
80 };
81
82 struct cxio_ucontext {
83         TAILQ_HEAD(, cxio_qpid) qpids;
84         struct mtx lock;
85 };
86
87 struct cxio_rdev {
88         char dev_name[T3_MAX_DEV_NAME_LEN];
89         struct t3cdev *t3cdev_p;
90         struct rdma_info rnic_info;
91         struct adap_ports port_info;
92         struct cxio_hal_resource *rscp;
93         struct cxio_hal_ctrl_qp ctrl_qp;
94         void *ulp;
95         unsigned long qpshift;
96         u32 qpnr;
97         u32 qpmask;
98         struct cxio_ucontext uctx;
99         struct gen_pool *pbl_pool;
100         struct gen_pool *rqt_pool;
101         struct ifnet *ifp;
102         TAILQ_ENTRY(cxio_rdev) entry;
103 };
104
105 static __inline int
106 cxio_num_stags(struct cxio_rdev *rdev_p)
107 {
108         return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5));
109 }
110
111 typedef void (*cxio_hal_ev_callback_func_t) (struct cxio_rdev * rdev_p,
112                                              struct mbuf * m);
113
114 #define RSPQ_CQID(rsp) (be32toh(rsp->cq_ptrid) & 0xffff)
115 #define RSPQ_CQPTR(rsp) ((be32toh(rsp->cq_ptrid) >> 16) & 0xffff)
116 #define RSPQ_GENBIT(rsp) ((be32toh(rsp->flags) >> 16) & 1)
117 #define RSPQ_OVERFLOW(rsp) ((be32toh(rsp->flags) >> 17) & 1)
118 #define RSPQ_AN(rsp) ((be32toh(rsp->flags) >> 18) & 1)
119 #define RSPQ_SE(rsp) ((be32toh(rsp->flags) >> 19) & 1)
120 #define RSPQ_NOTIFY(rsp) ((be32toh(rsp->flags) >> 20) & 1)
121 #define RSPQ_CQBRANCH(rsp) ((be32toh(rsp->flags) >> 21) & 1)
122 #define RSPQ_CREDIT_THRESH(rsp) ((be32toh(rsp->flags) >> 22) & 1)
123
124 struct respQ_msg_t {
125         __be32 flags;           /* flit 0 */
126         __be32 cq_ptrid;
127         __be64 rsvd;            /* flit 1 */
128         struct t3_cqe cqe;      /* flits 2-3 */
129 };
130
131 enum t3_cq_opcode {
132         CQ_ARM_AN = 0x2,
133         CQ_ARM_SE = 0x6,
134         CQ_FORCE_AN = 0x3,
135         CQ_CREDIT_UPDATE = 0x7
136 };
137
138 int cxio_rdev_open(struct cxio_rdev *rdev);
139 void cxio_rdev_close(struct cxio_rdev *rdev);
140 int cxio_hal_cq_op(struct cxio_rdev *rdev, struct t3_cq *cq,
141                    enum t3_cq_opcode op, u32 credit);
142 int cxio_create_cq(struct cxio_rdev *rdev, struct t3_cq *cq);
143 int cxio_destroy_cq(struct cxio_rdev *rdev, struct t3_cq *cq);
144 int cxio_resize_cq(struct cxio_rdev *rdev, struct t3_cq *cq);
145 void cxio_release_ucontext(struct cxio_rdev *rdev, struct cxio_ucontext *uctx);
146 void cxio_init_ucontext(struct cxio_rdev *rdev, struct cxio_ucontext *uctx);
147 int cxio_create_qp(struct cxio_rdev *rdev, u32 kernel_domain, struct t3_wq *wq,
148                    struct cxio_ucontext *uctx);
149 int cxio_destroy_qp(struct cxio_rdev *rdev, struct t3_wq *wq,
150                     struct cxio_ucontext *uctx);
151 int cxio_peek_cq(struct t3_wq *wr, struct t3_cq *cq, int opcode);
152 int cxio_register_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid,
153                            enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
154                            u8 page_size, __be64 *pbl, u32 *pbl_size,
155                            u32 *pbl_addr);
156 int cxio_reregister_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid,
157                            enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
158                            u8 page_size, __be64 *pbl, u32 *pbl_size,
159                            u32 *pbl_addr);
160 int cxio_dereg_mem(struct cxio_rdev *rdev, u32 stag, u32 pbl_size,
161                    u32 pbl_addr);
162 int cxio_allocate_window(struct cxio_rdev *rdev, u32 * stag, u32 pdid);
163 int cxio_deallocate_window(struct cxio_rdev *rdev, u32 stag);
164 int cxio_rdma_init(struct cxio_rdev *rdev, struct t3_rdma_init_attr *attr);
165 void cxio_register_ev_cb(cxio_hal_ev_callback_func_t ev_cb);
166 void cxio_unregister_ev_cb(cxio_hal_ev_callback_func_t ev_cb);
167 u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp);
168 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid);
169 int cxio_hal_init(void);
170 void cxio_hal_exit(void);
171 void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count);
172 void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count);
173 void cxio_count_rcqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
174 void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
175 void cxio_flush_hw_cq(struct t3_cq *cq);
176 int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
177                      u8 *cqe_flushed, u64 *cookie, u32 *credit);
178
179 #define MOD "iw_cxgb: "
180
181 #ifdef DEBUG
182 void cxio_dump_tpt(struct cxio_rdev *rev, u32 stag);
183 void cxio_dump_pbl(struct cxio_rdev *rev, u32 pbl_addr, uint32_t len, u8 shift);
184 void cxio_dump_wqe(union t3_wr *wqe);
185 void cxio_dump_wce(struct t3_cqe *wce);
186 void cxio_dump_rqt(struct cxio_rdev *rdev, u32 hwtid, int nents);
187 void cxio_dump_tcb(struct cxio_rdev *rdev, u32 hwtid);
188 #endif
189
190
191  static unsigned char hiBitSetTab[] = {
192     0, 1, 2, 2, 3, 3, 3, 3,
193     4, 4, 4, 4, 4, 4, 4, 4,
194     5, 5, 5, 5, 5, 5, 5, 5,
195     5, 5, 5, 5, 5, 5, 5, 5,
196     6, 6, 6, 6, 6, 6, 6, 6,
197     6, 6, 6, 6, 6, 6, 6, 6,
198     6, 6, 6, 6, 6, 6, 6, 6,
199     6, 6, 6, 6, 6, 6, 6, 6,
200     7, 7, 7, 7, 7, 7, 7, 7,
201     7, 7, 7, 7, 7, 7, 7, 7,
202     7, 7, 7, 7, 7, 7, 7, 7,
203     7, 7, 7, 7, 7, 7, 7, 7,
204     7, 7, 7, 7, 7, 7, 7, 7,
205     7, 7, 7, 7, 7, 7, 7, 7,
206     7, 7, 7, 7, 7, 7, 7, 7,
207     7, 7, 7, 7, 7, 7, 7, 7
208
209 };
210
211
212 static __inline
213 int ilog2(unsigned long val)
214 {
215     unsigned long   tmp;
216
217     tmp = val >> 24;
218     if (tmp) {
219         return hiBitSetTab[tmp] + 23;
220     }
221     tmp = (val >> 16) & 0xff;
222     if (tmp) {
223         return hiBitSetTab[tmp] + 15;
224     }
225     tmp = (val >> 8) & 0xff;
226     if (tmp) {
227         return hiBitSetTab[tmp] + 7;
228
229     }
230     return hiBitSetTab[val & 0xff] - 1;
231
232
233 #define cxfree(a) free((a), M_DEVBUF);
234 #define kmalloc(a, b) malloc((a), M_DEVBUF, (b))
235 #define kzalloc(a, b) malloc((a), M_DEVBUF, (b)|M_ZERO)
236
237 static __inline __attribute__((const))
238 unsigned long roundup_pow_of_two(unsigned long n)
239 {
240         return 1UL << flsl(n - 1);
241 }
242
243 #define PAGE_ALIGN(x) roundup2((x), PAGE_SIZE)
244
245 #include <sys/blist.h>
246 struct gen_pool {
247         blist_t         gen_list;
248         daddr_t         gen_base;
249         int             gen_chunk_shift;
250         struct mtx      gen_lock;
251 };
252
253 static __inline struct gen_pool *
254 gen_pool_create(daddr_t base, u_int chunk_shift, u_int len)
255 {
256         struct gen_pool *gp;
257
258         gp = malloc(sizeof(struct gen_pool), M_DEVBUF, M_NOWAIT);
259         if (gp == NULL)
260                 return (NULL);
261         
262         gp->gen_list = blist_create(len >> chunk_shift, M_NOWAIT);
263         if (gp->gen_list == NULL) {
264                 free(gp, M_DEVBUF);
265                 return (NULL);
266         }
267         blist_free(gp->gen_list, 0, len >> chunk_shift);
268         gp->gen_base = base;
269         gp->gen_chunk_shift = chunk_shift;
270         mtx_init(&gp->gen_lock, "genpool", NULL, MTX_DUPOK|MTX_DEF);
271
272         return (gp);
273 }
274
275 static __inline unsigned long
276 gen_pool_alloc(struct gen_pool *gp, int size)
277 {
278         int chunks;
279         daddr_t blkno; 
280
281         chunks = (size + (1<<gp->gen_chunk_shift) - 1) >> gp->gen_chunk_shift;
282         mtx_lock(&gp->gen_lock);
283         blkno = blist_alloc(gp->gen_list, chunks);
284         mtx_unlock(&gp->gen_lock);
285
286         if (blkno == SWAPBLK_NONE)
287                 return (0);
288
289         return (gp->gen_base + ((1 << gp->gen_chunk_shift) * blkno));
290 }
291
292 static __inline void
293 gen_pool_free(struct gen_pool *gp, daddr_t address, int size)
294 {
295         int chunks;
296         daddr_t blkno;
297         
298         chunks = (size + (1<<gp->gen_chunk_shift) - 1) >> gp->gen_chunk_shift;
299         blkno = (address - gp->gen_base) / (1 << gp->gen_chunk_shift);
300         mtx_lock(&gp->gen_lock);
301         blist_free(gp->gen_list, blkno, chunks);
302         mtx_unlock(&gp->gen_lock);
303 }
304
305 static __inline void
306 gen_pool_destroy(struct gen_pool *gp)
307 {
308         blist_destroy(gp->gen_list);
309         free(gp, M_DEVBUF);
310 }
311
312 #define cxio_wait(ctx, lockp, cond) \
313 ({ \
314         int __ret = 0; \
315         mtx_lock(lockp); \
316         while (!cond) { \
317                 msleep(ctx, lockp, 0, "cxio_wait", hz); \
318                 if (SIGPENDING(curthread)) { \
319                         __ret = ERESTART; \
320                         break; \
321                 } \
322         } \
323         mtx_unlock(lockp); \
324         __ret; \
325 }) 
326 extern struct cxio_rdev *cxio_hal_find_rdev_by_t3cdev(struct t3cdev *tdev);
327
328 #define KTR_IW_CXGB KTR_SPARE4
329
330 #endif