1 /**************************************************************************
3 Copyright (c) 2007, Chelsio Inc.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
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.
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.
28 ***************************************************************************/
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
38 #include <sys/pciio.h>
40 #include <machine/bus.h>
41 #include <machine/resource.h>
42 #include <sys/bus_dma.h>
44 #include <sys/ioccom.h>
46 #include <sys/rwlock.h>
47 #include <sys/linker.h>
48 #include <sys/firmware.h>
49 #include <sys/socket.h>
50 #include <sys/sockio.h>
52 #include <sys/sysctl.h>
53 #include <sys/queue.h>
54 #include <sys/taskqueue.h>
56 #include <sys/eventhandler.h>
58 #include <netinet/in.h>
59 #include <netinet/toecore.h>
61 #include <rdma/ib_verbs.h>
62 #include <linux/idr.h>
63 #include <ulp/iw_cxgb/iw_cxgb_ib_intfc.h>
66 #include <cxgb_include.h>
67 #include <ulp/iw_cxgb/iw_cxgb_wr.h>
68 #include <ulp/iw_cxgb/iw_cxgb_hal.h>
69 #include <ulp/iw_cxgb/iw_cxgb_provider.h>
70 #include <ulp/iw_cxgb/iw_cxgb_cm.h>
71 #include <ulp/iw_cxgb/iw_cxgb.h>
73 static int iwch_mod_load(void);
74 static int iwch_mod_unload(void);
75 static int iwch_activate(struct adapter *);
76 static int iwch_deactivate(struct adapter *);
78 static struct uld_info iwch_uld_info = {
80 .activate = iwch_activate,
81 .deactivate = iwch_deactivate,
85 rnic_init(struct iwch_dev *rnicp)
88 idr_init(&rnicp->cqidr);
89 idr_init(&rnicp->qpidr);
90 idr_init(&rnicp->mmidr);
91 mtx_init(&rnicp->lock, "iwch rnic lock", NULL, MTX_DEF|MTX_DUPOK);
93 rnicp->attr.vendor_id = 0x168;
94 rnicp->attr.vendor_part_id = 7;
95 rnicp->attr.max_qps = T3_MAX_NUM_QP - 32;
96 rnicp->attr.max_wrs = T3_MAX_QP_DEPTH;
97 rnicp->attr.max_sge_per_wr = T3_MAX_SGE;
98 rnicp->attr.max_sge_per_rdma_write_wr = T3_MAX_SGE;
99 rnicp->attr.max_cqs = T3_MAX_NUM_CQ - 1;
100 rnicp->attr.max_cqes_per_cq = T3_MAX_CQ_DEPTH;
101 rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev);
102 rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE;
103 rnicp->attr.max_pds = T3_MAX_NUM_PD - 1;
104 rnicp->attr.mem_pgsizes_bitmask = T3_PAGESIZE_MASK;
105 rnicp->attr.max_mr_size = T3_MAX_MR_SIZE;
106 rnicp->attr.can_resize_wq = 0;
107 rnicp->attr.max_rdma_reads_per_qp = 8;
108 rnicp->attr.max_rdma_read_resources =
109 rnicp->attr.max_rdma_reads_per_qp * rnicp->attr.max_qps;
110 rnicp->attr.max_rdma_read_qp_depth = 8; /* IRD */
111 rnicp->attr.max_rdma_read_depth =
112 rnicp->attr.max_rdma_read_qp_depth * rnicp->attr.max_qps;
113 rnicp->attr.rq_overflow_handled = 0;
114 rnicp->attr.can_modify_ird = 0;
115 rnicp->attr.can_modify_ord = 0;
116 rnicp->attr.max_mem_windows = rnicp->attr.max_mem_regs - 1;
117 rnicp->attr.stag0_value = 1;
118 rnicp->attr.zbva_support = 1;
119 rnicp->attr.local_invalidate_fence = 1;
120 rnicp->attr.cq_overflow_detection = 1;
126 rnic_uninit(struct iwch_dev *rnicp)
128 idr_destroy(&rnicp->cqidr);
129 idr_destroy(&rnicp->qpidr);
130 idr_destroy(&rnicp->mmidr);
131 mtx_destroy(&rnicp->lock);
135 iwch_activate(struct adapter *sc)
137 struct iwch_dev *rnicp;
140 KASSERT(!isset(&sc->offload_map, MAX_NPORTS),
141 ("%s: iWARP already activated on %s", __func__,
142 device_get_nameunit(sc->dev)));
144 rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp));
148 sc->iwarp_softc = rnicp;
149 rnicp->rdev.adap = sc;
152 iwch_cm_init_cpl(sc);
154 rc = cxio_rdev_open(&rnicp->rdev);
156 printf("Unable to open CXIO rdev\n");
162 rc = iwch_register_device(rnicp);
164 printf("Unable to register device\n");
172 cxio_rdev_close(&rnicp->rdev);
175 iwch_cm_term_cpl(sc);
176 sc->iwarp_softc = NULL;
182 iwch_deactivate(struct adapter *sc)
184 struct iwch_dev *rnicp;
186 rnicp = sc->iwarp_softc;
188 iwch_unregister_device(rnicp);
190 cxio_rdev_close(&rnicp->rdev);
192 iwch_cm_term_cpl(sc);
193 ib_dealloc_device(&rnicp->ibdev);
195 sc->iwarp_softc = NULL;
201 iwch_activate_all(struct adapter *sc, void *arg __unused)
204 if ((sc->open_device_map & sc->offload_map) != 0 &&
205 t3_activate_uld(sc, ULD_IWARP) == 0)
206 setbit(&sc->offload_map, MAX_NPORTS);
211 iwch_deactivate_all(struct adapter *sc, void *arg __unused)
214 if (isset(&sc->offload_map, MAX_NPORTS) &&
215 t3_deactivate_uld(sc, ULD_IWARP) == 0)
216 clrbit(&sc->offload_map, MAX_NPORTS);
229 rc = t3_register_uld(&iwch_uld_info);
235 t3_iterate(iwch_activate_all, NULL);
241 iwch_mod_unload(void)
243 t3_iterate(iwch_deactivate_all, NULL);
247 if (t3_unregister_uld(&iwch_uld_info) == EBUSY)
252 #endif /* TCP_OFFLOAD */
254 #undef MODULE_VERSION
255 #include <sys/module.h>
258 iwch_modevent(module_t mod, int cmd, void *arg)
265 rc = iwch_mod_load();
267 printf("iw_cxgb: Chelsio T3 RDMA Driver failed to load\n");
269 printf("iw_cxgb: Chelsio T3 RDMA Driver loaded\n");
273 rc = iwch_mod_unload();
275 printf("iw_cxgb: Chelsio T3 RDMA Driver failed to unload\n");
277 printf("iw_cxgb: Chelsio T3 RDMA Driver unloaded\n");
284 printf("iw_cxgb: compiled without TCP_OFFLOAD support.\n");
290 static moduledata_t iwch_mod_data = {
296 MODULE_VERSION(iw_cxgb, 1);
297 DECLARE_MODULE(iw_cxgb, iwch_mod_data, SI_SUB_EXEC, SI_ORDER_ANY);
298 MODULE_DEPEND(t3_tom, cxgbc, 1, 1, 1);
299 MODULE_DEPEND(iw_cxgb, toecore, 1, 1, 1);
300 MODULE_DEPEND(iw_cxgb, t3_tom, 1, 1, 1);
301 MODULE_DEPEND(iw_cxgb, ibcore, 1, 1, 1);