1256694Snp/*
2256694Snp * Copyright (c) 2009-2013 Chelsio, Inc. All rights reserved.
3256694Snp *
4256694Snp * This software is available to you under a choice of one of two
5256694Snp * licenses.  You may choose to be licensed under the terms of the GNU
6256694Snp * General Public License (GPL) Version 2, available from the file
7256694Snp * COPYING in the main directory of this source tree, or the
8256694Snp * OpenIB.org BSD license below:
9256694Snp *
10256694Snp *     Redistribution and use in source and binary forms, with or
11256694Snp *     without modification, are permitted provided that the following
12256694Snp *     conditions are met:
13256694Snp *
14256694Snp *      - Redistributions of source code must retain the above
15256694Snp *	  copyright notice, this list of conditions and the following
16256694Snp *	  disclaimer.
17256694Snp *      - Redistributions in binary form must reproduce the above
18256694Snp *	  copyright notice, this list of conditions and the following
19256694Snp *	  disclaimer in the documentation and/or other materials
20256694Snp *	  provided with the distribution.
21256694Snp *
22256694Snp * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23256694Snp * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24256694Snp * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25256694Snp * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
26256694Snp * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27256694Snp * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28256694Snp * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29256694Snp * SOFTWARE.
30256694Snp *
31256694Snp * $FreeBSD$
32256694Snp */
33256694Snp#ifndef __IW_CXGB4_H__
34256694Snp#define __IW_CXGB4_H__
35256694Snp
36256694Snp#include <linux/list.h>
37256694Snp#include <linux/spinlock.h>
38256694Snp#include <linux/idr.h>
39256694Snp#include <linux/completion.h>
40256694Snp#include <linux/netdevice.h>
41256694Snp#include <linux/sched.h>
42256694Snp#include <linux/pci.h>
43256694Snp#include <linux/dma-mapping.h>
44256694Snp#include <linux/inet.h>
45256694Snp#include <linux/wait.h>
46256694Snp#include <linux/kref.h>
47256694Snp#include <linux/timer.h>
48256694Snp#include <linux/io.h>
49256694Snp
50256694Snp#include <asm/byteorder.h>
51256694Snp
52256694Snp#include <netinet/in.h>
53256694Snp#include <netinet/toecore.h>
54256694Snp
55256694Snp#include <rdma/ib_verbs.h>
56256694Snp#include <rdma/iw_cm.h>
57256694Snp
58256694Snp#undef prefetch
59256694Snp
60256694Snp#include "common/common.h"
61256694Snp#include "common/t4_msg.h"
62256694Snp#include "common/t4_regs.h"
63256694Snp#include "common/t4_tcb.h"
64256694Snp#include "t4_l2t.h"
65256694Snp
66256694Snp#define DRV_NAME "iw_cxgbe"
67256694Snp#define MOD DRV_NAME ":"
68256694Snp#define KTR_IW_CXGBE	KTR_SPARE3
69256694Snp
70256694Snpextern int c4iw_debug;
71256694Snp#define PDBG(fmt, args...) \
72256694Snpdo { \
73256694Snp	if (c4iw_debug) \
74256694Snp		printf(MOD fmt, ## args); \
75256694Snp} while (0)
76256694Snp
77256694Snp#include "t4.h"
78256694Snp
79256694Snpstatic inline void *cplhdr(struct mbuf *m)
80256694Snp{
81256694Snp	return mtod(m, void*);
82256694Snp}
83256694Snp
84256694Snp#define PBL_OFF(rdev_p, a) ((a) - (rdev_p)->adap->vres.pbl.start)
85256694Snp#define RQT_OFF(rdev_p, a) ((a) - (rdev_p)->adap->vres.rq.start)
86256694Snp
87256694Snp#define C4IW_ID_TABLE_F_RANDOM 1       /* Pseudo-randomize the id's returned */
88256694Snp#define C4IW_ID_TABLE_F_EMPTY  2       /* Table is initially empty */
89256694Snp
90256694Snpstruct c4iw_id_table {
91256694Snp	u32 flags;
92256694Snp	u32 start;              /* logical minimal id */
93256694Snp	u32 last;               /* hint for find */
94256694Snp	u32 max;
95256694Snp	spinlock_t lock;
96256694Snp	unsigned long *table;
97256694Snp};
98256694Snp
99256694Snpstruct c4iw_resource {
100256694Snp	struct c4iw_id_table tpt_table;
101256694Snp	struct c4iw_id_table qid_table;
102256694Snp	struct c4iw_id_table pdid_table;
103256694Snp};
104256694Snp
105256694Snpstruct c4iw_qid_list {
106256694Snp	struct list_head entry;
107256694Snp	u32 qid;
108256694Snp};
109256694Snp
110256694Snpstruct c4iw_dev_ucontext {
111256694Snp	struct list_head qpids;
112256694Snp	struct list_head cqids;
113256694Snp	struct mutex lock;
114256694Snp};
115256694Snp
116256694Snpenum c4iw_rdev_flags {
117256694Snp	T4_FATAL_ERROR = (1<<0),
118256694Snp};
119256694Snp
120256694Snpstruct c4iw_stat {
121256694Snp	u64 total;
122256694Snp	u64 cur;
123256694Snp	u64 max;
124256694Snp	u64 fail;
125256694Snp};
126256694Snp
127256694Snpstruct c4iw_stats {
128256694Snp	struct mutex lock;
129256694Snp	struct c4iw_stat qid;
130256694Snp	struct c4iw_stat pd;
131256694Snp	struct c4iw_stat stag;
132256694Snp	struct c4iw_stat pbl;
133256694Snp	struct c4iw_stat rqt;
134256694Snp	u64  db_full;
135256694Snp	u64  db_empty;
136256694Snp	u64  db_drop;
137256694Snp	u64  db_state_transitions;
138256694Snp};
139256694Snp
140256694Snpstruct c4iw_rdev {
141256694Snp	struct adapter *adap;
142256694Snp	struct c4iw_resource resource;
143256694Snp	unsigned long qpshift;
144256694Snp	u32 qpmask;
145256694Snp	unsigned long cqshift;
146256694Snp	u32 cqmask;
147256694Snp	struct c4iw_dev_ucontext uctx;
148256694Snp	struct gen_pool *pbl_pool;
149256694Snp	struct gen_pool *rqt_pool;
150256694Snp	u32 flags;
151256694Snp	struct c4iw_stats stats;
152256694Snp};
153256694Snp
154256694Snpstatic inline int c4iw_fatal_error(struct c4iw_rdev *rdev)
155256694Snp{
156256694Snp	return rdev->flags & T4_FATAL_ERROR;
157256694Snp}
158256694Snp
159256694Snpstatic inline int c4iw_num_stags(struct c4iw_rdev *rdev)
160256694Snp{
161256694Snp	return min((int)T4_MAX_NUM_STAG, (int)(rdev->adap->vres.stag.size >> 5));
162256694Snp}
163256694Snp
164256694Snp#define C4IW_WR_TO (10*HZ)
165256694Snp
166256694Snpstruct c4iw_wr_wait {
167256694Snp	int ret;
168256694Snp	atomic_t completion;
169256694Snp};
170256694Snp
171256694Snpstatic inline void c4iw_init_wr_wait(struct c4iw_wr_wait *wr_waitp)
172256694Snp{
173256694Snp	wr_waitp->ret = 0;
174256694Snp	atomic_set(&wr_waitp->completion, 0);
175256694Snp}
176256694Snp
177256694Snpstatic inline void c4iw_wake_up(struct c4iw_wr_wait *wr_waitp, int ret)
178256694Snp{
179256694Snp	wr_waitp->ret = ret;
180256694Snp	atomic_set(&wr_waitp->completion, 1);
181256694Snp	wakeup(wr_waitp);
182256694Snp}
183256694Snp
184256694Snpstatic inline int
185256694Snpc4iw_wait_for_reply(struct c4iw_rdev *rdev, struct c4iw_wr_wait *wr_waitp,
186256694Snp    u32 hwtid, u32 qpid, const char *func)
187256694Snp{
188256694Snp	struct adapter *sc = rdev->adap;
189256694Snp	unsigned to = C4IW_WR_TO;
190256694Snp
191256694Snp	while (!atomic_read(&wr_waitp->completion)) {
192256694Snp                tsleep(wr_waitp, 0, "c4iw_wait", to);
193256694Snp                if (SIGPENDING(curthread)) {
194256694Snp			printf("%s - Device %s not responding - "
195256694Snp			    "tid %u qpid %u\n", func,
196256694Snp			    device_get_nameunit(sc->dev), hwtid, qpid);
197256694Snp                        if (c4iw_fatal_error(rdev)) {
198256694Snp                                wr_waitp->ret = -EIO;
199256694Snp                                break;
200256694Snp                        }
201256694Snp                        to = to << 2;
202256694Snp                }
203256694Snp        }
204256694Snp	if (wr_waitp->ret)
205256694Snp		CTR4(KTR_IW_CXGBE, "%s: FW reply %d tid %u qpid %u",
206256694Snp		    device_get_nameunit(sc->dev), wr_waitp->ret, hwtid, qpid);
207256694Snp	return (wr_waitp->ret);
208256694Snp}
209256694Snp
210256694Snpenum db_state {
211256694Snp	NORMAL = 0,
212256694Snp	FLOW_CONTROL = 1,
213256694Snp	RECOVERY = 2
214256694Snp};
215256694Snp
216256694Snpstruct c4iw_dev {
217256694Snp	struct ib_device ibdev;
218256694Snp	struct c4iw_rdev rdev;
219256694Snp	u32 device_cap_flags;
220256694Snp	struct idr cqidr;
221256694Snp	struct idr qpidr;
222256694Snp	struct idr mmidr;
223256694Snp	spinlock_t lock;
224256694Snp	struct dentry *debugfs_root;
225256694Snp	enum db_state db_state;
226256694Snp	int qpcnt;
227256694Snp};
228256694Snp
229256694Snpstatic inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)
230256694Snp{
231256694Snp	return container_of(ibdev, struct c4iw_dev, ibdev);
232256694Snp}
233256694Snp
234256694Snpstatic inline struct c4iw_dev *rdev_to_c4iw_dev(struct c4iw_rdev *rdev)
235256694Snp{
236256694Snp	return container_of(rdev, struct c4iw_dev, rdev);
237256694Snp}
238256694Snp
239256694Snpstatic inline struct c4iw_cq *get_chp(struct c4iw_dev *rhp, u32 cqid)
240256694Snp{
241256694Snp	return idr_find(&rhp->cqidr, cqid);
242256694Snp}
243256694Snp
244256694Snpstatic inline struct c4iw_qp *get_qhp(struct c4iw_dev *rhp, u32 qpid)
245256694Snp{
246256694Snp	return idr_find(&rhp->qpidr, qpid);
247256694Snp}
248256694Snp
249256694Snpstatic inline struct c4iw_mr *get_mhp(struct c4iw_dev *rhp, u32 mmid)
250256694Snp{
251256694Snp	return idr_find(&rhp->mmidr, mmid);
252256694Snp}
253256694Snp
254256694Snpstatic inline int _insert_handle(struct c4iw_dev *rhp, struct idr *idr,
255256694Snp				 void *handle, u32 id, int lock)
256256694Snp{
257256694Snp	int ret;
258256694Snp	int newid;
259256694Snp
260256694Snp	do {
261256694Snp		if (!idr_pre_get(idr, lock ? GFP_KERNEL : GFP_ATOMIC))
262256694Snp			return -ENOMEM;
263256694Snp		if (lock)
264256694Snp			spin_lock_irq(&rhp->lock);
265256694Snp		ret = idr_get_new_above(idr, handle, id, &newid);
266256694Snp		BUG_ON(!ret && newid != id);
267256694Snp		if (lock)
268256694Snp			spin_unlock_irq(&rhp->lock);
269256694Snp	} while (ret == -EAGAIN);
270256694Snp
271256694Snp	return ret;
272256694Snp}
273256694Snp
274256694Snpstatic inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
275256694Snp				void *handle, u32 id)
276256694Snp{
277256694Snp	return _insert_handle(rhp, idr, handle, id, 1);
278256694Snp}
279256694Snp
280256694Snpstatic inline int insert_handle_nolock(struct c4iw_dev *rhp, struct idr *idr,
281256694Snp				       void *handle, u32 id)
282256694Snp{
283256694Snp	return _insert_handle(rhp, idr, handle, id, 0);
284256694Snp}
285256694Snp
286256694Snpstatic inline void _remove_handle(struct c4iw_dev *rhp, struct idr *idr,
287256694Snp				   u32 id, int lock)
288256694Snp{
289256694Snp	if (lock)
290256694Snp		spin_lock_irq(&rhp->lock);
291256694Snp	idr_remove(idr, id);
292256694Snp	if (lock)
293256694Snp		spin_unlock_irq(&rhp->lock);
294256694Snp}
295256694Snp
296256694Snpstatic inline void remove_handle(struct c4iw_dev *rhp, struct idr *idr, u32 id)
297256694Snp{
298256694Snp	_remove_handle(rhp, idr, id, 1);
299256694Snp}
300256694Snp
301256694Snpstatic inline void remove_handle_nolock(struct c4iw_dev *rhp,
302256694Snp					 struct idr *idr, u32 id)
303256694Snp{
304256694Snp	_remove_handle(rhp, idr, id, 0);
305256694Snp}
306256694Snp
307256694Snpstruct c4iw_pd {
308256694Snp	struct ib_pd ibpd;
309256694Snp	u32 pdid;
310256694Snp	struct c4iw_dev *rhp;
311256694Snp};
312256694Snp
313256694Snpstatic inline struct c4iw_pd *to_c4iw_pd(struct ib_pd *ibpd)
314256694Snp{
315256694Snp	return container_of(ibpd, struct c4iw_pd, ibpd);
316256694Snp}
317256694Snp
318256694Snpstruct tpt_attributes {
319256694Snp	u64 len;
320256694Snp	u64 va_fbo;
321256694Snp	enum fw_ri_mem_perms perms;
322256694Snp	u32 stag;
323256694Snp	u32 pdid;
324256694Snp	u32 qpid;
325256694Snp	u32 pbl_addr;
326256694Snp	u32 pbl_size;
327256694Snp	u32 state:1;
328256694Snp	u32 type:2;
329256694Snp	u32 rsvd:1;
330256694Snp	u32 remote_invaliate_disable:1;
331256694Snp	u32 zbva:1;
332256694Snp	u32 mw_bind_enable:1;
333256694Snp	u32 page_size:5;
334256694Snp};
335256694Snp
336256694Snpstruct c4iw_mr {
337256694Snp	struct ib_mr ibmr;
338256694Snp	struct ib_umem *umem;
339256694Snp	struct c4iw_dev *rhp;
340256694Snp	u64 kva;
341256694Snp	struct tpt_attributes attr;
342256694Snp};
343256694Snp
344256694Snpstatic inline struct c4iw_mr *to_c4iw_mr(struct ib_mr *ibmr)
345256694Snp{
346256694Snp	return container_of(ibmr, struct c4iw_mr, ibmr);
347256694Snp}
348256694Snp
349256694Snpstruct c4iw_mw {
350256694Snp	struct ib_mw ibmw;
351256694Snp	struct c4iw_dev *rhp;
352256694Snp	u64 kva;
353256694Snp	struct tpt_attributes attr;
354256694Snp};
355256694Snp
356256694Snpstatic inline struct c4iw_mw *to_c4iw_mw(struct ib_mw *ibmw)
357256694Snp{
358256694Snp	return container_of(ibmw, struct c4iw_mw, ibmw);
359256694Snp}
360256694Snp
361256694Snpstruct c4iw_fr_page_list {
362256694Snp	struct ib_fast_reg_page_list ibpl;
363256694Snp	DECLARE_PCI_UNMAP_ADDR(mapping);
364256694Snp	dma_addr_t dma_addr;
365256694Snp	struct c4iw_dev *dev;
366256694Snp	int size;
367256694Snp};
368256694Snp
369256694Snpstatic inline struct c4iw_fr_page_list *to_c4iw_fr_page_list(
370256694Snp					struct ib_fast_reg_page_list *ibpl)
371256694Snp{
372256694Snp	return container_of(ibpl, struct c4iw_fr_page_list, ibpl);
373256694Snp}
374256694Snp
375256694Snpstruct c4iw_cq {
376256694Snp	struct ib_cq ibcq;
377256694Snp	struct c4iw_dev *rhp;
378256694Snp	struct t4_cq cq;
379256694Snp	spinlock_t lock;
380256694Snp	spinlock_t comp_handler_lock;
381256694Snp	atomic_t refcnt;
382256694Snp	wait_queue_head_t wait;
383256694Snp};
384256694Snp
385256694Snpstatic inline struct c4iw_cq *to_c4iw_cq(struct ib_cq *ibcq)
386256694Snp{
387256694Snp	return container_of(ibcq, struct c4iw_cq, ibcq);
388256694Snp}
389256694Snp
390256694Snpstruct c4iw_mpa_attributes {
391256694Snp	u8 initiator;
392256694Snp	u8 recv_marker_enabled;
393256694Snp	u8 xmit_marker_enabled;
394256694Snp	u8 crc_enabled;
395256694Snp	u8 enhanced_rdma_conn;
396256694Snp	u8 version;
397256694Snp	u8 p2p_type;
398256694Snp};
399256694Snp
400256694Snpstruct c4iw_qp_attributes {
401256694Snp	u32 scq;
402256694Snp	u32 rcq;
403256694Snp	u32 sq_num_entries;
404256694Snp	u32 rq_num_entries;
405256694Snp	u32 sq_max_sges;
406256694Snp	u32 sq_max_sges_rdma_write;
407256694Snp	u32 rq_max_sges;
408256694Snp	u32 state;
409256694Snp	u8 enable_rdma_read;
410256694Snp	u8 enable_rdma_write;
411256694Snp	u8 enable_bind;
412256694Snp	u8 enable_mmid0_fastreg;
413256694Snp	u32 max_ord;
414256694Snp	u32 max_ird;
415256694Snp	u32 pd;
416256694Snp	u32 next_state;
417256694Snp	char terminate_buffer[52];
418256694Snp	u32 terminate_msg_len;
419256694Snp	u8 is_terminate_local;
420256694Snp	struct c4iw_mpa_attributes mpa_attr;
421256694Snp	struct c4iw_ep *llp_stream_handle;
422256694Snp	u8 layer_etype;
423256694Snp	u8 ecode;
424256694Snp	u16 sq_db_inc;
425256694Snp	u16 rq_db_inc;
426256694Snp};
427256694Snp
428256694Snpstruct c4iw_qp {
429256694Snp	struct ib_qp ibqp;
430256694Snp	struct c4iw_dev *rhp;
431256694Snp	struct c4iw_ep *ep;
432256694Snp	struct c4iw_qp_attributes attr;
433256694Snp	struct t4_wq wq;
434256694Snp	spinlock_t lock;
435256694Snp	struct mutex mutex;
436256694Snp	atomic_t refcnt;
437256694Snp	wait_queue_head_t wait;
438256694Snp	struct timer_list timer;
439256694Snp};
440256694Snp
441256694Snpstatic inline struct c4iw_qp *to_c4iw_qp(struct ib_qp *ibqp)
442256694Snp{
443256694Snp	return container_of(ibqp, struct c4iw_qp, ibqp);
444256694Snp}
445256694Snp
446256694Snpstruct c4iw_ucontext {
447256694Snp	struct ib_ucontext ibucontext;
448256694Snp	struct c4iw_dev_ucontext uctx;
449256694Snp	u32 key;
450256694Snp	spinlock_t mmap_lock;
451256694Snp	struct list_head mmaps;
452256694Snp};
453256694Snp
454256694Snpstatic inline struct c4iw_ucontext *to_c4iw_ucontext(struct ib_ucontext *c)
455256694Snp{
456256694Snp	return container_of(c, struct c4iw_ucontext, ibucontext);
457256694Snp}
458256694Snp
459256694Snpstruct c4iw_mm_entry {
460256694Snp	struct list_head entry;
461256694Snp	u64 addr;
462256694Snp	u32 key;
463256694Snp	unsigned len;
464256694Snp};
465256694Snp
466256694Snpstatic inline struct c4iw_mm_entry *remove_mmap(struct c4iw_ucontext *ucontext,
467256694Snp						u32 key, unsigned len)
468256694Snp{
469256694Snp	struct list_head *pos, *nxt;
470256694Snp	struct c4iw_mm_entry *mm;
471256694Snp
472256694Snp	spin_lock(&ucontext->mmap_lock);
473256694Snp	list_for_each_safe(pos, nxt, &ucontext->mmaps) {
474256694Snp
475256694Snp		mm = list_entry(pos, struct c4iw_mm_entry, entry);
476256694Snp		if (mm->key == key && mm->len == len) {
477256694Snp			list_del_init(&mm->entry);
478256694Snp			spin_unlock(&ucontext->mmap_lock);
479256694Snp			CTR4(KTR_IW_CXGBE, "%s key 0x%x addr 0x%llx len %d",
480256694Snp			     __func__, key, (unsigned long long) mm->addr,
481256694Snp			     mm->len);
482256694Snp			return mm;
483256694Snp		}
484256694Snp	}
485256694Snp	spin_unlock(&ucontext->mmap_lock);
486256694Snp	return NULL;
487256694Snp}
488256694Snp
489256694Snpstatic inline void insert_mmap(struct c4iw_ucontext *ucontext,
490256694Snp			       struct c4iw_mm_entry *mm)
491256694Snp{
492256694Snp	spin_lock(&ucontext->mmap_lock);
493256694Snp	CTR4(KTR_IW_CXGBE, "%s key 0x%x addr 0x%llx len %d", __func__, mm->key,
494256694Snp	    (unsigned long long) mm->addr, mm->len);
495256694Snp	list_add_tail(&mm->entry, &ucontext->mmaps);
496256694Snp	spin_unlock(&ucontext->mmap_lock);
497256694Snp}
498256694Snp
499256694Snpenum c4iw_qp_attr_mask {
500256694Snp	C4IW_QP_ATTR_NEXT_STATE = 1 << 0,
501256694Snp	C4IW_QP_ATTR_SQ_DB = 1<<1,
502256694Snp	C4IW_QP_ATTR_RQ_DB = 1<<2,
503256694Snp	C4IW_QP_ATTR_ENABLE_RDMA_READ = 1 << 7,
504256694Snp	C4IW_QP_ATTR_ENABLE_RDMA_WRITE = 1 << 8,
505256694Snp	C4IW_QP_ATTR_ENABLE_RDMA_BIND = 1 << 9,
506256694Snp	C4IW_QP_ATTR_MAX_ORD = 1 << 11,
507256694Snp	C4IW_QP_ATTR_MAX_IRD = 1 << 12,
508256694Snp	C4IW_QP_ATTR_LLP_STREAM_HANDLE = 1 << 22,
509256694Snp	C4IW_QP_ATTR_STREAM_MSG_BUFFER = 1 << 23,
510256694Snp	C4IW_QP_ATTR_MPA_ATTR = 1 << 24,
511256694Snp	C4IW_QP_ATTR_QP_CONTEXT_ACTIVATE = 1 << 25,
512256694Snp	C4IW_QP_ATTR_VALID_MODIFY = (C4IW_QP_ATTR_ENABLE_RDMA_READ |
513256694Snp				     C4IW_QP_ATTR_ENABLE_RDMA_WRITE |
514256694Snp				     C4IW_QP_ATTR_MAX_ORD |
515256694Snp				     C4IW_QP_ATTR_MAX_IRD |
516256694Snp				     C4IW_QP_ATTR_LLP_STREAM_HANDLE |
517256694Snp				     C4IW_QP_ATTR_STREAM_MSG_BUFFER |
518256694Snp				     C4IW_QP_ATTR_MPA_ATTR |
519256694Snp				     C4IW_QP_ATTR_QP_CONTEXT_ACTIVATE)
520256694Snp};
521256694Snp
522256694Snpint c4iw_modify_qp(struct c4iw_dev *rhp,
523256694Snp				struct c4iw_qp *qhp,
524256694Snp				enum c4iw_qp_attr_mask mask,
525256694Snp				struct c4iw_qp_attributes *attrs,
526256694Snp				int internal);
527256694Snp
528256694Snpenum c4iw_qp_state {
529256694Snp	C4IW_QP_STATE_IDLE,
530256694Snp	C4IW_QP_STATE_RTS,
531256694Snp	C4IW_QP_STATE_ERROR,
532256694Snp	C4IW_QP_STATE_TERMINATE,
533256694Snp	C4IW_QP_STATE_CLOSING,
534256694Snp	C4IW_QP_STATE_TOT
535256694Snp};
536256694Snp
537256694Snpstatic inline int c4iw_convert_state(enum ib_qp_state ib_state)
538256694Snp{
539256694Snp	switch (ib_state) {
540256694Snp	case IB_QPS_RESET:
541256694Snp	case IB_QPS_INIT:
542256694Snp		return C4IW_QP_STATE_IDLE;
543256694Snp	case IB_QPS_RTS:
544256694Snp		return C4IW_QP_STATE_RTS;
545256694Snp	case IB_QPS_SQD:
546256694Snp		return C4IW_QP_STATE_CLOSING;
547256694Snp	case IB_QPS_SQE:
548256694Snp		return C4IW_QP_STATE_TERMINATE;
549256694Snp	case IB_QPS_ERR:
550256694Snp		return C4IW_QP_STATE_ERROR;
551256694Snp	default:
552256694Snp		return -1;
553256694Snp	}
554256694Snp}
555256694Snp
556256694Snpstatic inline int to_ib_qp_state(int c4iw_qp_state)
557256694Snp{
558256694Snp	switch (c4iw_qp_state) {
559256694Snp	case C4IW_QP_STATE_IDLE:
560256694Snp		return IB_QPS_INIT;
561256694Snp	case C4IW_QP_STATE_RTS:
562256694Snp		return IB_QPS_RTS;
563256694Snp	case C4IW_QP_STATE_CLOSING:
564256694Snp		return IB_QPS_SQD;
565256694Snp	case C4IW_QP_STATE_TERMINATE:
566256694Snp		return IB_QPS_SQE;
567256694Snp	case C4IW_QP_STATE_ERROR:
568256694Snp		return IB_QPS_ERR;
569256694Snp	}
570256694Snp	return IB_QPS_ERR;
571256694Snp}
572256694Snp
573256694Snpstatic inline u32 c4iw_ib_to_tpt_access(int a)
574256694Snp{
575256694Snp	return (a & IB_ACCESS_REMOTE_WRITE ? FW_RI_MEM_ACCESS_REM_WRITE : 0) |
576256694Snp	       (a & IB_ACCESS_REMOTE_READ ? FW_RI_MEM_ACCESS_REM_READ : 0) |
577256694Snp	       (a & IB_ACCESS_LOCAL_WRITE ? FW_RI_MEM_ACCESS_LOCAL_WRITE : 0) |
578256694Snp	       FW_RI_MEM_ACCESS_LOCAL_READ;
579256694Snp}
580256694Snp
581256694Snpstatic inline u32 c4iw_ib_to_tpt_bind_access(int acc)
582256694Snp{
583256694Snp	return (acc & IB_ACCESS_REMOTE_WRITE ? FW_RI_MEM_ACCESS_REM_WRITE : 0) |
584256694Snp	       (acc & IB_ACCESS_REMOTE_READ ? FW_RI_MEM_ACCESS_REM_READ : 0);
585256694Snp}
586256694Snp
587256694Snpenum c4iw_mmid_state {
588256694Snp	C4IW_STAG_STATE_VALID,
589256694Snp	C4IW_STAG_STATE_INVALID
590256694Snp};
591256694Snp
592256694Snp#define C4IW_NODE_DESC "iw_cxgbe Chelsio Communications"
593256694Snp
594256694Snp#define MPA_KEY_REQ "MPA ID Req Frame"
595256694Snp#define MPA_KEY_REP "MPA ID Rep Frame"
596256694Snp
597256694Snp#define MPA_MAX_PRIVATE_DATA	256
598256694Snp#define MPA_ENHANCED_RDMA_CONN	0x10
599256694Snp#define MPA_REJECT		0x20
600256694Snp#define MPA_CRC			0x40
601256694Snp#define MPA_MARKERS		0x80
602256694Snp#define MPA_FLAGS_MASK		0xE0
603256694Snp
604256694Snp#define MPA_V2_PEER2PEER_MODEL          0x8000
605256694Snp#define MPA_V2_ZERO_LEN_FPDU_RTR        0x4000
606256694Snp#define MPA_V2_RDMA_WRITE_RTR           0x8000
607256694Snp#define MPA_V2_RDMA_READ_RTR            0x4000
608256694Snp#define MPA_V2_IRD_ORD_MASK             0x3FFF
609256694Snp
610256694Snp/* Fixme: Use atomic_read for kref.count as same as Linux */
611256694Snp#define c4iw_put_ep(ep) { \
612256694Snp	CTR4(KTR_IW_CXGBE, "put_ep (%s:%u) ep %p, refcnt %d", \
613256694Snp	     __func__, __LINE__, ep, (ep)->kref.count); \
614256694Snp	WARN_ON((ep)->kref.count < 1); \
615256694Snp        kref_put(&((ep)->kref), _c4iw_free_ep); \
616256694Snp}
617256694Snp
618256694Snp/* Fixme: Use atomic_read for kref.count as same as Linux */
619256694Snp#define c4iw_get_ep(ep) { \
620256694Snp	CTR4(KTR_IW_CXGBE, "get_ep (%s:%u) ep %p, refcnt %d", \
621256694Snp	      __func__, __LINE__, ep, (ep)->kref.count); \
622256694Snp        kref_get(&((ep)->kref));  \
623256694Snp}
624256694Snp
625256694Snpvoid _c4iw_free_ep(struct kref *kref);
626256694Snp
627256694Snpstruct mpa_message {
628256694Snp	u8 key[16];
629256694Snp	u8 flags;
630256694Snp	u8 revision;
631256694Snp	__be16 private_data_size;
632256694Snp	u8 private_data[0];
633256694Snp};
634256694Snp
635256694Snpstruct mpa_v2_conn_params {
636256694Snp	__be16 ird;
637256694Snp	__be16 ord;
638256694Snp};
639256694Snp
640256694Snpstruct terminate_message {
641256694Snp	u8 layer_etype;
642256694Snp	u8 ecode;
643256694Snp	__be16 hdrct_rsvd;
644256694Snp	u8 len_hdrs[0];
645256694Snp};
646256694Snp
647256694Snp#define TERM_MAX_LENGTH (sizeof(struct terminate_message) + 2 + 18 + 28)
648256694Snp
649256694Snpenum c4iw_layers_types {
650256694Snp	LAYER_RDMAP		= 0x00,
651256694Snp	LAYER_DDP		= 0x10,
652256694Snp	LAYER_MPA		= 0x20,
653256694Snp	RDMAP_LOCAL_CATA	= 0x00,
654256694Snp	RDMAP_REMOTE_PROT	= 0x01,
655256694Snp	RDMAP_REMOTE_OP		= 0x02,
656256694Snp	DDP_LOCAL_CATA		= 0x00,
657256694Snp	DDP_TAGGED_ERR		= 0x01,
658256694Snp	DDP_UNTAGGED_ERR	= 0x02,
659256694Snp	DDP_LLP			= 0x03
660256694Snp};
661256694Snp
662256694Snpenum c4iw_rdma_ecodes {
663256694Snp	RDMAP_INV_STAG		= 0x00,
664256694Snp	RDMAP_BASE_BOUNDS	= 0x01,
665256694Snp	RDMAP_ACC_VIOL		= 0x02,
666256694Snp	RDMAP_STAG_NOT_ASSOC	= 0x03,
667256694Snp	RDMAP_TO_WRAP		= 0x04,
668256694Snp	RDMAP_INV_VERS		= 0x05,
669256694Snp	RDMAP_INV_OPCODE	= 0x06,
670256694Snp	RDMAP_STREAM_CATA	= 0x07,
671256694Snp	RDMAP_GLOBAL_CATA	= 0x08,
672256694Snp	RDMAP_CANT_INV_STAG	= 0x09,
673256694Snp	RDMAP_UNSPECIFIED	= 0xff
674256694Snp};
675256694Snp
676256694Snpenum c4iw_ddp_ecodes {
677256694Snp	DDPT_INV_STAG		= 0x00,
678256694Snp	DDPT_BASE_BOUNDS	= 0x01,
679256694Snp	DDPT_STAG_NOT_ASSOC	= 0x02,
680256694Snp	DDPT_TO_WRAP		= 0x03,
681256694Snp	DDPT_INV_VERS		= 0x04,
682256694Snp	DDPU_INV_QN		= 0x01,
683256694Snp	DDPU_INV_MSN_NOBUF	= 0x02,
684256694Snp	DDPU_INV_MSN_RANGE	= 0x03,
685256694Snp	DDPU_INV_MO		= 0x04,
686256694Snp	DDPU_MSG_TOOBIG		= 0x05,
687256694Snp	DDPU_INV_VERS		= 0x06
688256694Snp};
689256694Snp
690256694Snpenum c4iw_mpa_ecodes {
691256694Snp	MPA_CRC_ERR		= 0x02,
692256694Snp	MPA_MARKER_ERR		= 0x03,
693256694Snp	MPA_LOCAL_CATA          = 0x05,
694256694Snp	MPA_INSUFF_IRD          = 0x06,
695256694Snp	MPA_NOMATCH_RTR         = 0x07,
696256694Snp};
697256694Snp
698256694Snpenum c4iw_ep_state {
699256694Snp	IDLE = 0,
700256694Snp	LISTEN,
701256694Snp	CONNECTING,
702256694Snp	MPA_REQ_WAIT,
703256694Snp	MPA_REQ_SENT,
704256694Snp	MPA_REQ_RCVD,
705256694Snp	MPA_REP_SENT,
706256694Snp	FPDU_MODE,
707256694Snp	ABORTING,
708256694Snp	CLOSING,
709256694Snp	MORIBUND,
710256694Snp	DEAD,
711256694Snp};
712256694Snp
713256694Snpenum c4iw_ep_flags {
714256694Snp	PEER_ABORT_IN_PROGRESS	= 0,
715256694Snp	ABORT_REQ_IN_PROGRESS	= 1,
716256694Snp	RELEASE_RESOURCES	= 2,
717256694Snp	CLOSE_SENT		= 3,
718256694Snp	TIMEOUT                 = 4
719256694Snp};
720256694Snp
721256694Snpenum c4iw_ep_history {
722256694Snp        ACT_OPEN_REQ            = 0,
723256694Snp        ACT_OFLD_CONN           = 1,
724256694Snp        ACT_OPEN_RPL            = 2,
725256694Snp        ACT_ESTAB               = 3,
726256694Snp        PASS_ACCEPT_REQ         = 4,
727256694Snp        PASS_ESTAB              = 5,
728256694Snp        ABORT_UPCALL            = 6,
729256694Snp        ESTAB_UPCALL            = 7,
730256694Snp        CLOSE_UPCALL            = 8,
731256694Snp        ULP_ACCEPT              = 9,
732256694Snp        ULP_REJECT              = 10,
733256694Snp        TIMEDOUT                = 11,
734256694Snp        PEER_ABORT              = 12,
735256694Snp        PEER_CLOSE              = 13,
736256694Snp        CONNREQ_UPCALL          = 14,
737256694Snp        ABORT_CONN              = 15,
738256694Snp        DISCONN_UPCALL          = 16,
739256694Snp        EP_DISC_CLOSE           = 17,
740256694Snp        EP_DISC_ABORT           = 18,
741256694Snp        CONN_RPL_UPCALL         = 19,
742256694Snp        ACT_RETRY_NOMEM         = 20,
743256694Snp        ACT_RETRY_INUSE         = 21
744256694Snp};
745256694Snp
746256694Snpstruct c4iw_ep_common {
747256694Snp	TAILQ_ENTRY(c4iw_ep_common) entry;	/* Work queue attachment */
748256694Snp	struct iw_cm_id *cm_id;
749256694Snp	struct c4iw_qp *qp;
750256694Snp	struct c4iw_dev *dev;
751256694Snp	enum c4iw_ep_state state;
752256694Snp	struct kref kref;
753256694Snp	struct mutex mutex;
754256694Snp	struct sockaddr_in local_addr;
755256694Snp	struct sockaddr_in remote_addr;
756256694Snp	struct c4iw_wr_wait wr_wait;
757256694Snp	unsigned long flags;
758256694Snp	unsigned long history;
759256694Snp        int rpl_err;
760256694Snp        int rpl_done;
761256694Snp        struct thread *thread;
762256694Snp        struct socket *so;
763256694Snp};
764256694Snp
765256694Snpstruct c4iw_listen_ep {
766256694Snp	struct c4iw_ep_common com;
767256694Snp	unsigned int stid;
768256694Snp	int backlog;
769256694Snp};
770256694Snp
771256694Snpstruct c4iw_ep {
772256694Snp	struct c4iw_ep_common com;
773256694Snp	struct c4iw_ep *parent_ep;
774256694Snp	struct timer_list timer;
775256694Snp	struct list_head entry;
776256694Snp	unsigned int atid;
777256694Snp	u32 hwtid;
778256694Snp	u32 snd_seq;
779256694Snp	u32 rcv_seq;
780256694Snp	struct l2t_entry *l2t;
781256694Snp	struct dst_entry *dst;
782256694Snp	struct c4iw_mpa_attributes mpa_attr;
783256694Snp	u8 mpa_pkt[sizeof(struct mpa_message) + MPA_MAX_PRIVATE_DATA];
784256694Snp	unsigned int mpa_pkt_len;
785256694Snp	u32 ird;
786256694Snp	u32 ord;
787256694Snp	u32 smac_idx;
788256694Snp	u32 tx_chan;
789256694Snp	u32 mtu;
790256694Snp	u16 mss;
791256694Snp	u16 emss;
792256694Snp	u16 plen;
793256694Snp	u16 rss_qid;
794256694Snp	u16 txq_idx;
795256694Snp	u16 ctrlq_idx;
796256694Snp	u8 tos;
797256694Snp	u8 retry_with_mpa_v1;
798256694Snp	u8 tried_with_mpa_v1;
799256694Snp};
800256694Snp
801256694Snpstatic inline struct c4iw_ep *to_ep(struct iw_cm_id *cm_id)
802256694Snp{
803256694Snp	return cm_id->provider_data;
804256694Snp}
805256694Snp
806256694Snpstatic inline struct c4iw_listen_ep *to_listen_ep(struct iw_cm_id *cm_id)
807256694Snp{
808256694Snp	return cm_id->provider_data;
809256694Snp}
810256694Snp
811256694Snpstatic inline int compute_wscale(int win)
812256694Snp{
813256694Snp	int wscale = 0;
814256694Snp
815256694Snp	while (wscale < 14 && (65535<<wscale) < win)
816256694Snp		wscale++;
817256694Snp	return wscale;
818256694Snp}
819256694Snp
820256694Snpu32 c4iw_id_alloc(struct c4iw_id_table *alloc);
821256694Snpvoid c4iw_id_free(struct c4iw_id_table *alloc, u32 obj);
822256694Snpint c4iw_id_table_alloc(struct c4iw_id_table *alloc, u32 start, u32 num,
823256694Snp			u32 reserved, u32 flags);
824256694Snpvoid c4iw_id_table_free(struct c4iw_id_table *alloc);
825256694Snp
826256694Snptypedef int (*c4iw_handler_func)(struct c4iw_dev *dev, struct mbuf *m);
827256694Snp
828256694Snpint c4iw_ep_redirect(void *ctx, struct dst_entry *old, struct dst_entry *new,
829256694Snp		     struct l2t_entry *l2t);
830256694Snpu32 c4iw_get_resource(struct c4iw_id_table *id_table);
831256694Snpvoid c4iw_put_resource(struct c4iw_id_table *id_table, u32 entry);
832256694Snpint c4iw_init_resource(struct c4iw_rdev *rdev, u32 nr_tpt, u32 nr_pdid);
833256694Snpint c4iw_init_ctrl_qp(struct c4iw_rdev *rdev);
834256694Snpint c4iw_pblpool_create(struct c4iw_rdev *rdev);
835256694Snpint c4iw_rqtpool_create(struct c4iw_rdev *rdev);
836256694Snpvoid c4iw_pblpool_destroy(struct c4iw_rdev *rdev);
837256694Snpvoid c4iw_rqtpool_destroy(struct c4iw_rdev *rdev);
838256694Snpvoid c4iw_destroy_resource(struct c4iw_resource *rscp);
839256694Snpint c4iw_destroy_ctrl_qp(struct c4iw_rdev *rdev);
840256694Snpint c4iw_register_device(struct c4iw_dev *dev);
841256694Snpvoid c4iw_unregister_device(struct c4iw_dev *dev);
842256694Snpint __init c4iw_cm_init(void);
843256694Snpvoid __exit c4iw_cm_term(void);
844256694Snpvoid c4iw_release_dev_ucontext(struct c4iw_rdev *rdev,
845256694Snp			       struct c4iw_dev_ucontext *uctx);
846256694Snpvoid c4iw_init_dev_ucontext(struct c4iw_rdev *rdev,
847256694Snp			    struct c4iw_dev_ucontext *uctx);
848256694Snpint c4iw_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
849256694Snpint c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
850256694Snp		      struct ib_send_wr **bad_wr);
851256694Snpint c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
852256694Snp		      struct ib_recv_wr **bad_wr);
853256694Snpint c4iw_bind_mw(struct ib_qp *qp, struct ib_mw *mw,
854256694Snp		 struct ib_mw_bind *mw_bind);
855256694Snpint c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
856256694Snpint c4iw_create_listen(struct iw_cm_id *cm_id, int backlog);
857256694Snpint c4iw_destroy_listen(struct iw_cm_id *cm_id);
858256694Snpint c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
859256694Snpint c4iw_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len);
860256694Snpvoid c4iw_qp_add_ref(struct ib_qp *qp);
861256694Snpvoid c4iw_qp_rem_ref(struct ib_qp *qp);
862256694Snpvoid c4iw_free_fastreg_pbl(struct ib_fast_reg_page_list *page_list);
863256694Snpstruct ib_fast_reg_page_list *c4iw_alloc_fastreg_pbl(
864256694Snp					struct ib_device *device,
865256694Snp					int page_list_len);
866256694Snpstruct ib_mr *c4iw_alloc_fast_reg_mr(struct ib_pd *pd, int pbl_depth);
867256694Snpint c4iw_dealloc_mw(struct ib_mw *mw);
868256694Snpstruct ib_mw *c4iw_alloc_mw(struct ib_pd *pd);
869256694Snpstruct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64
870256694Snp    virt, int acc, struct ib_udata *udata, int mr_id);
871256694Snpstruct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc);
872256694Snpstruct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd,
873256694Snp					struct ib_phys_buf *buffer_list,
874256694Snp					int num_phys_buf,
875256694Snp					int acc,
876256694Snp					u64 *iova_start);
877256694Snpint c4iw_reregister_phys_mem(struct ib_mr *mr,
878256694Snp				     int mr_rereg_mask,
879256694Snp				     struct ib_pd *pd,
880256694Snp				     struct ib_phys_buf *buffer_list,
881256694Snp				     int num_phys_buf,
882256694Snp				     int acc, u64 *iova_start);
883256694Snpint c4iw_dereg_mr(struct ib_mr *ib_mr);
884256694Snpint c4iw_destroy_cq(struct ib_cq *ib_cq);
885256694Snpstruct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries,
886256694Snp					int vector,
887256694Snp					struct ib_ucontext *ib_context,
888256694Snp					struct ib_udata *udata);
889256694Snpint c4iw_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata);
890256694Snpint c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
891256694Snpint c4iw_destroy_qp(struct ib_qp *ib_qp);
892256694Snpstruct ib_qp *c4iw_create_qp(struct ib_pd *pd,
893256694Snp			     struct ib_qp_init_attr *attrs,
894256694Snp			     struct ib_udata *udata);
895256694Snpint c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
896256694Snp				 int attr_mask, struct ib_udata *udata);
897256694Snpint c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
898256694Snp		     int attr_mask, struct ib_qp_init_attr *init_attr);
899256694Snpstruct ib_qp *c4iw_get_qp(struct ib_device *dev, int qpn);
900256694Snpu32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size);
901256694Snpvoid c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size);
902256694Snpu32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size);
903256694Snpvoid c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size);
904256694Snpint c4iw_ofld_send(struct c4iw_rdev *rdev, struct mbuf *m);
905256694Snpvoid c4iw_flush_hw_cq(struct t4_cq *cq);
906256694Snpvoid c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count);
907256694Snpvoid c4iw_count_scqes(struct t4_cq *cq, struct t4_wq *wq, int *count);
908256694Snpint c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp);
909256694Snpint c4iw_flush_rq(struct t4_wq *wq, struct t4_cq *cq, int count);
910256694Snpint c4iw_flush_sq(struct t4_wq *wq, struct t4_cq *cq, int count);
911256694Snpint c4iw_ev_handler(struct sge_iq *, const struct rsp_ctrl *);
912256694Snpu16 c4iw_rqes_posted(struct c4iw_qp *qhp);
913256694Snpint c4iw_post_terminate(struct c4iw_qp *qhp, struct t4_cqe *err_cqe);
914256694Snpu32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx);
915256694Snpvoid c4iw_put_cqid(struct c4iw_rdev *rdev, u32 qid,
916256694Snp		struct c4iw_dev_ucontext *uctx);
917256694Snpu32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx);
918256694Snpvoid c4iw_put_qpid(struct c4iw_rdev *rdev, u32 qid,
919256694Snp		struct c4iw_dev_ucontext *uctx);
920256694Snpvoid c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe);
921256694Snp
922256694Snpextern struct cxgb4_client t4c_client;
923256694Snpextern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS];
924256694Snpextern int c4iw_max_read_depth;
925256694Snp
926256694Snp#include <sys/blist.h>
927256694Snpstruct gen_pool {
928256694Snp        blist_t         gen_list;
929256694Snp        daddr_t         gen_base;
930256694Snp        int             gen_chunk_shift;
931256694Snp        struct mutex      gen_lock;
932256694Snp};
933256694Snp
934256694Snpstatic __inline struct gen_pool *
935256694Snpgen_pool_create(daddr_t base, u_int chunk_shift, u_int len)
936256694Snp{
937256694Snp        struct gen_pool *gp;
938256694Snp
939256694Snp        gp = malloc(sizeof(struct gen_pool), M_DEVBUF, M_NOWAIT);
940256694Snp        if (gp == NULL)
941256694Snp                return (NULL);
942256694Snp
943256694Snp        memset(gp, 0, sizeof(struct gen_pool));
944256694Snp        gp->gen_list = blist_create(len >> chunk_shift, M_NOWAIT);
945256694Snp        if (gp->gen_list == NULL) {
946256694Snp                free(gp, M_DEVBUF);
947256694Snp                return (NULL);
948256694Snp        }
949256694Snp        blist_free(gp->gen_list, 0, len >> chunk_shift);
950256694Snp        gp->gen_base = base;
951256694Snp        gp->gen_chunk_shift = chunk_shift;
952256694Snp        //mutex_init(&gp->gen_lock, "genpool", NULL, MTX_DUPOK|MTX_DEF);
953256694Snp        mutex_init(&gp->gen_lock);
954256694Snp
955256694Snp        return (gp);
956256694Snp}
957256694Snp
958256694Snpstatic __inline unsigned long
959256694Snpgen_pool_alloc(struct gen_pool *gp, int size)
960256694Snp{
961256694Snp        int chunks;
962256694Snp        daddr_t blkno;
963256694Snp
964256694Snp        chunks = (size + (1<<gp->gen_chunk_shift) - 1) >> gp->gen_chunk_shift;
965256694Snp        mutex_lock(&gp->gen_lock);
966256694Snp        blkno = blist_alloc(gp->gen_list, chunks);
967256694Snp        mutex_unlock(&gp->gen_lock);
968256694Snp
969256694Snp        if (blkno == SWAPBLK_NONE)
970256694Snp                return (0);
971256694Snp
972256694Snp        return (gp->gen_base + ((1 << gp->gen_chunk_shift) * blkno));
973256694Snp}
974256694Snp
975256694Snpstatic __inline void
976256694Snpgen_pool_free(struct gen_pool *gp, daddr_t address, int size)
977256694Snp{
978256694Snp        int chunks;
979256694Snp        daddr_t blkno;
980256694Snp
981256694Snp        chunks = (size + (1<<gp->gen_chunk_shift) - 1) >> gp->gen_chunk_shift;
982256694Snp        blkno = (address - gp->gen_base) / (1 << gp->gen_chunk_shift);
983256694Snp        mutex_lock(&gp->gen_lock);
984256694Snp        blist_free(gp->gen_list, blkno, chunks);
985256694Snp        mutex_unlock(&gp->gen_lock);
986256694Snp}
987256694Snp
988256694Snpstatic __inline void
989256694Snpgen_pool_destroy(struct gen_pool *gp)
990256694Snp{
991256694Snp        blist_destroy(gp->gen_list);
992256694Snp        free(gp, M_DEVBUF);
993256694Snp}
994256694Snp
995256694Snp#if defined(__i386__) || defined(__amd64__)
996256694Snp#define L1_CACHE_BYTES 128
997256694Snp#else
998256694Snp#define L1_CACHE_BYTES 32
999256694Snp#endif
1000256694Snp
1001256694Snpstatic inline
1002256694Snpint idr_for_each(struct idr *idp,
1003256694Snp                 int (*fn)(int id, void *p, void *data), void *data)
1004256694Snp{
1005256694Snp        int n, id, max, error = 0;
1006256694Snp        struct idr_layer *p;
1007256694Snp        struct idr_layer *pa[MAX_LEVEL];
1008256694Snp        struct idr_layer **paa = &pa[0];
1009256694Snp
1010256694Snp        n = idp->layers * IDR_BITS;
1011256694Snp        p = idp->top;
1012256694Snp        max = 1 << n;
1013256694Snp
1014256694Snp        id = 0;
1015256694Snp        while (id < max) {
1016256694Snp                while (n > 0 && p) {
1017256694Snp                        n -= IDR_BITS;
1018256694Snp                        *paa++ = p;
1019256694Snp                        p = p->ary[(id >> n) & IDR_MASK];
1020256694Snp                }
1021256694Snp
1022256694Snp                if (p) {
1023256694Snp                        error = fn(id, (void *)p, data);
1024256694Snp                        if (error)
1025256694Snp                                break;
1026256694Snp                }
1027256694Snp
1028256694Snp                id += 1 << n;
1029256694Snp                while (n < fls(id)) {
1030256694Snp                        n += IDR_BITS;
1031256694Snp                        p = *--paa;
1032256694Snp                }
1033256694Snp        }
1034256694Snp
1035256694Snp        return error;
1036256694Snp}
1037256694Snp
1038256694Snpvoid c4iw_cm_init_cpl(struct adapter *);
1039256694Snpvoid c4iw_cm_term_cpl(struct adapter *);
1040256694Snp
1041256694Snpvoid your_reg_device(struct c4iw_dev *dev);
1042256694Snp
1043256694Snp#define SGE_CTRLQ_NUM	0
1044256694Snp
1045256694Snpextern int spg_creds;/* Status Page size in credit units(1 unit = 64) */
1046256694Snp#endif
1047