Deleted Added
sdiff udiff text old ( 183550 ) new ( 185571 )
full compact
1/**************************************************************************
2
3Copyright (c) 2007, Chelsio Inc.
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26POSSIBILITY OF SUCH DAMAGE.
27
28***************************************************************************/
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb.c 185571 2008-12-02 21:37:28Z bz $");
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/kernel.h>
35#include <sys/bus.h>
36#include <sys/module.h>
37#include <sys/pciio.h>
38#include <sys/conf.h>
39#include <machine/bus.h>
40#include <machine/resource.h>
41#include <sys/bus_dma.h>
42#include <sys/rman.h>
43#include <sys/ioccom.h>
44#include <sys/mbuf.h>
45#include <sys/rwlock.h>
46#include <sys/linker.h>
47#include <sys/firmware.h>
48#include <sys/socket.h>
49#include <sys/sockio.h>
50#include <sys/smp.h>
51#include <sys/sysctl.h>
52#include <sys/queue.h>
53#include <sys/taskqueue.h>
54#include <sys/proc.h>
55#include <sys/eventhandler.h>
56
57#if __FreeBSD_version >= 800044
58#include <sys/vimage.h>
59#else
60#define V_ifnet ifnet
61#endif
62
63#include <net/if.h>
64#include <net/if_var.h>
65#if __FreeBSD_version >= 800056
66#include <net/vnet.h>
67#endif
68
69#include <netinet/in.h>
70
71#include <contrib/rdma/ib_verbs.h>
72
73#include <cxgb_include.h>
74#include <ulp/iw_cxgb/iw_cxgb_wr.h>
75#include <ulp/iw_cxgb/iw_cxgb_hal.h>
76#include <ulp/iw_cxgb/iw_cxgb_provider.h>
77#include <ulp/iw_cxgb/iw_cxgb_cm.h>
78#include <ulp/iw_cxgb/iw_cxgb.h>
79
80/*
81 * XXX :-/
82 *
83 */
84
85#define idr_init(x)
86
87cxgb_cpl_handler_func t3c_handlers[NUM_CPL_CMDS];
88
89static void open_rnic_dev(struct t3cdev *);
90static void close_rnic_dev(struct t3cdev *);
91
92static TAILQ_HEAD( ,iwch_dev) dev_list;
93static struct mtx dev_mutex;
94static eventhandler_tag event_tag;
95
96static void
97rnic_init(struct iwch_dev *rnicp)
98{
99 CTR2(KTR_IW_CXGB, "%s iwch_dev %p", __FUNCTION__, rnicp);
100 idr_init(&rnicp->cqidr);
101 idr_init(&rnicp->qpidr);
102 idr_init(&rnicp->mmidr);
103 mtx_init(&rnicp->lock, "iwch rnic lock", NULL, MTX_DEF|MTX_DUPOK);
104
105 rnicp->attr.vendor_id = 0x168;
106 rnicp->attr.vendor_part_id = 7;
107 rnicp->attr.max_qps = T3_MAX_NUM_QP - 32;
108 rnicp->attr.max_wrs = (1UL << 24) - 1;
109 rnicp->attr.max_sge_per_wr = T3_MAX_SGE;
110 rnicp->attr.max_sge_per_rdma_write_wr = T3_MAX_SGE;
111 rnicp->attr.max_cqs = T3_MAX_NUM_CQ - 1;
112 rnicp->attr.max_cqes_per_cq = (1UL << 24) - 1;
113 rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev);
114 rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE;
115 rnicp->attr.max_pds = T3_MAX_NUM_PD - 1;
116 rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */
117 rnicp->attr.can_resize_wq = 0;
118 rnicp->attr.max_rdma_reads_per_qp = 8;
119 rnicp->attr.max_rdma_read_resources =
120 rnicp->attr.max_rdma_reads_per_qp * rnicp->attr.max_qps;
121 rnicp->attr.max_rdma_read_qp_depth = 8; /* IRD */
122 rnicp->attr.max_rdma_read_depth =
123 rnicp->attr.max_rdma_read_qp_depth * rnicp->attr.max_qps;
124 rnicp->attr.rq_overflow_handled = 0;
125 rnicp->attr.can_modify_ird = 0;
126 rnicp->attr.can_modify_ord = 0;
127 rnicp->attr.max_mem_windows = rnicp->attr.max_mem_regs - 1;
128 rnicp->attr.stag0_value = 1;
129 rnicp->attr.zbva_support = 1;
130 rnicp->attr.local_invalidate_fence = 1;
131 rnicp->attr.cq_overflow_detection = 1;
132 return;
133}
134
135static void
136open_rnic_dev(struct t3cdev *tdev)
137{
138 struct iwch_dev *rnicp;
139 static int vers_printed;
140
141 CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev);
142 if (!vers_printed++)
143 printf("Chelsio T3 RDMA Driver - version %s\n",
144 DRV_VERSION);
145 rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp));
146 if (!rnicp) {
147 printf("Cannot allocate ib device\n");
148 return;
149 }
150 rnicp->rdev.ulp = rnicp;
151 rnicp->rdev.t3cdev_p = tdev;
152
153 mtx_lock(&dev_mutex);
154
155 if (cxio_rdev_open(&rnicp->rdev)) {
156 mtx_unlock(&dev_mutex);
157 printf("Unable to open CXIO rdev\n");
158 ib_dealloc_device(&rnicp->ibdev);
159 return;
160 }
161
162 rnic_init(rnicp);
163
164 TAILQ_INSERT_TAIL(&dev_list, rnicp, entry);
165 mtx_unlock(&dev_mutex);
166
167 if (iwch_register_device(rnicp)) {
168 printf("Unable to register device\n");
169 close_rnic_dev(tdev);
170 }
171#ifdef notyet
172 printf("Initialized device %s\n",
173 pci_name(rnicp->rdev.rnic_info.pdev));
174#endif
175 return;
176}
177
178static void
179close_rnic_dev(struct t3cdev *tdev)
180{
181 struct iwch_dev *dev, *tmp;
182 CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev);
183 mtx_lock(&dev_mutex);
184
185 TAILQ_FOREACH_SAFE(dev, &dev_list, entry, tmp) {
186 if (dev->rdev.t3cdev_p == tdev) {
187#ifdef notyet
188 list_del(&dev->entry);
189 iwch_unregister_device(dev);
190 cxio_rdev_close(&dev->rdev);
191 idr_destroy(&dev->cqidr);
192 idr_destroy(&dev->qpidr);
193 idr_destroy(&dev->mmidr);
194 ib_dealloc_device(&dev->ibdev);
195#endif
196 break;
197 }
198 }
199 mtx_unlock(&dev_mutex);
200}
201
202static ifaddr_event_handler_t
203ifaddr_event_handler(void *arg, struct ifnet *ifp)
204{
205 printf("%s if name %s \n", __FUNCTION__, ifp->if_xname);
206 if (ifp->if_capabilities & IFCAP_TOE4) {
207 KASSERT(T3CDEV(ifp) != NULL, ("null t3cdev ptr!"));
208 if (cxio_hal_find_rdev_by_t3cdev(T3CDEV(ifp)) == NULL)
209 open_rnic_dev(T3CDEV(ifp));
210 }
211 return 0;
212}
213
214
215static int
216iwch_init_module(void)
217{
218 VNET_ITERATOR_DECL(vnet_iter);
219 int err;
220 struct ifnet *ifp;
221
222 printf("%s enter\n", __FUNCTION__);
223 TAILQ_INIT(&dev_list);
224 mtx_init(&dev_mutex, "iwch dev_list lock", NULL, MTX_DEF);
225
226 err = cxio_hal_init();
227 if (err)
228 return err;
229 err = iwch_cm_init();
230 if (err)
231 return err;
232 cxio_register_ev_cb(iwch_ev_dispatch);
233
234 /* Register for ifaddr events to dynamically add TOE devs */
235 event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_event_handler,
236 NULL, EVENTHANDLER_PRI_ANY);
237
238 /* Register existing TOE interfaces by walking the ifnet chain */
239 IFNET_RLOCK();
240 VNET_LIST_RLOCK();
241 VNET_FOREACH(vnet_iter) {
242 CURVNET_SET(vnet_iter); /* XXX CURVNET_SET_QUIET() ? */
243 INIT_VNET_NET(vnet_iter);
244 TAILQ_FOREACH(ifp, &V_ifnet, if_link)
245 (void)ifaddr_event_handler(NULL, ifp);
246 CURVNET_RESTORE();
247 }
248 VNET_LIST_RUNLOCK();
249 IFNET_RUNLOCK();
250 return 0;
251}
252
253static void
254iwch_exit_module(void)
255{
256 EVENTHANDLER_DEREGISTER(ifaddr_event, event_tag);
257 cxio_unregister_ev_cb(iwch_ev_dispatch);
258 iwch_cm_term();
259 cxio_hal_exit();
260}
261
262static int
263iwch_load(module_t mod, int cmd, void *arg)
264{
265 int err = 0;
266
267 switch (cmd) {
268 case MOD_LOAD:
269 printf("Loading iw_cxgb.\n");
270
271 iwch_init_module();
272 break;
273 case MOD_QUIESCE:
274 break;
275 case MOD_UNLOAD:
276 printf("Unloading iw_cxgb.\n");
277 iwch_exit_module();
278 break;
279 case MOD_SHUTDOWN:
280 break;
281 default:
282 err = EOPNOTSUPP;
283 break;
284 }
285
286 return (err);
287}
288
289static moduledata_t mod_data = {
290 "iw_cxgb",
291 iwch_load,
292 0
293};
294
295MODULE_VERSION(iw_cxgb, 1);
296DECLARE_MODULE(iw_cxgb, mod_data, SI_SUB_EXEC, SI_ORDER_ANY);
297MODULE_DEPEND(iw_cxgb, rdma_core, 1, 1, 1);
298MODULE_DEPEND(iw_cxgb, if_cxgb, 1, 1, 1);
299MODULE_DEPEND(iw_cxgb, t3_tom, 1, 1, 1);
300