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 183550 2008-10-02 15:37:58Z zec $");
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
66#include <netinet/in.h>
67
68#include <contrib/rdma/ib_verbs.h>
69
70#include <cxgb_include.h>
71#include <ulp/iw_cxgb/iw_cxgb_wr.h>
72#include <ulp/iw_cxgb/iw_cxgb_hal.h>
73#include <ulp/iw_cxgb/iw_cxgb_provider.h>
74#include <ulp/iw_cxgb/iw_cxgb_cm.h>
75#include <ulp/iw_cxgb/iw_cxgb.h>
76
77/*
78 * XXX :-/
79 *
80 */
81
82#define idr_init(x)
83
84cxgb_cpl_handler_func t3c_handlers[NUM_CPL_CMDS];
85
86static void open_rnic_dev(struct t3cdev *);
87static void close_rnic_dev(struct t3cdev *);
88
89static TAILQ_HEAD( ,iwch_dev) dev_list;
90static struct mtx dev_mutex;
91static eventhandler_tag event_tag;
92
93static void
94rnic_init(struct iwch_dev *rnicp)
95{
96 CTR2(KTR_IW_CXGB, "%s iwch_dev %p", __FUNCTION__, rnicp);
97 idr_init(&rnicp->cqidr);
98 idr_init(&rnicp->qpidr);
99 idr_init(&rnicp->mmidr);
100 mtx_init(&rnicp->lock, "iwch rnic lock", NULL, MTX_DEF|MTX_DUPOK);
101
102 rnicp->attr.vendor_id = 0x168;
103 rnicp->attr.vendor_part_id = 7;
104 rnicp->attr.max_qps = T3_MAX_NUM_QP - 32;
105 rnicp->attr.max_wrs = (1UL << 24) - 1;
106 rnicp->attr.max_sge_per_wr = T3_MAX_SGE;
107 rnicp->attr.max_sge_per_rdma_write_wr = T3_MAX_SGE;
108 rnicp->attr.max_cqs = T3_MAX_NUM_CQ - 1;
109 rnicp->attr.max_cqes_per_cq = (1UL << 24) - 1;
110 rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev);
111 rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE;
112 rnicp->attr.max_pds = T3_MAX_NUM_PD - 1;
113 rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */
114 rnicp->attr.can_resize_wq = 0;
115 rnicp->attr.max_rdma_reads_per_qp = 8;
116 rnicp->attr.max_rdma_read_resources =
117 rnicp->attr.max_rdma_reads_per_qp * rnicp->attr.max_qps;
118 rnicp->attr.max_rdma_read_qp_depth = 8; /* IRD */
119 rnicp->attr.max_rdma_read_depth =
120 rnicp->attr.max_rdma_read_qp_depth * rnicp->attr.max_qps;
121 rnicp->attr.rq_overflow_handled = 0;
122 rnicp->attr.can_modify_ird = 0;
123 rnicp->attr.can_modify_ord = 0;
124 rnicp->attr.max_mem_windows = rnicp->attr.max_mem_regs - 1;
125 rnicp->attr.stag0_value = 1;
126 rnicp->attr.zbva_support = 1;
127 rnicp->attr.local_invalidate_fence = 1;
128 rnicp->attr.cq_overflow_detection = 1;
129 return;
130}
131
132static void
133open_rnic_dev(struct t3cdev *tdev)
134{
135 struct iwch_dev *rnicp;
136 static int vers_printed;
137
138 CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev);
139 if (!vers_printed++)
140 printf("Chelsio T3 RDMA Driver - version %s\n",
141 DRV_VERSION);
142 rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp));
143 if (!rnicp) {
144 printf("Cannot allocate ib device\n");
145 return;
146 }
147 rnicp->rdev.ulp = rnicp;
148 rnicp->rdev.t3cdev_p = tdev;
149
150 mtx_lock(&dev_mutex);
151
152 if (cxio_rdev_open(&rnicp->rdev)) {
153 mtx_unlock(&dev_mutex);
154 printf("Unable to open CXIO rdev\n");
155 ib_dealloc_device(&rnicp->ibdev);
156 return;
157 }
158
159 rnic_init(rnicp);
160
161 TAILQ_INSERT_TAIL(&dev_list, rnicp, entry);
162 mtx_unlock(&dev_mutex);
163
164 if (iwch_register_device(rnicp)) {
165 printf("Unable to register device\n");
166 close_rnic_dev(tdev);
167 }
168#ifdef notyet
169 printf("Initialized device %s\n",
170 pci_name(rnicp->rdev.rnic_info.pdev));
171#endif
172 return;
173}
174
175static void
176close_rnic_dev(struct t3cdev *tdev)
177{
178 struct iwch_dev *dev, *tmp;
179 CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev);
180 mtx_lock(&dev_mutex);
181
182 TAILQ_FOREACH_SAFE(dev, &dev_list, entry, tmp) {
183 if (dev->rdev.t3cdev_p == tdev) {
184#ifdef notyet
185 list_del(&dev->entry);
186 iwch_unregister_device(dev);
187 cxio_rdev_close(&dev->rdev);
188 idr_destroy(&dev->cqidr);
189 idr_destroy(&dev->qpidr);
190 idr_destroy(&dev->mmidr);
191 ib_dealloc_device(&dev->ibdev);
192#endif
193 break;
194 }
195 }
196 mtx_unlock(&dev_mutex);
197}
198
199static ifaddr_event_handler_t
200ifaddr_event_handler(void *arg, struct ifnet *ifp)
201{
202 printf("%s if name %s \n", __FUNCTION__, ifp->if_xname);
203 if (ifp->if_capabilities & IFCAP_TOE4) {
204 KASSERT(T3CDEV(ifp) != NULL, ("null t3cdev ptr!"));
205 if (cxio_hal_find_rdev_by_t3cdev(T3CDEV(ifp)) == NULL)
206 open_rnic_dev(T3CDEV(ifp));
207 }
208 return 0;
209}
210
211
212static int
213iwch_init_module(void)
214{
215 VNET_ITERATOR_DECL(vnet_iter);
216 int err;
217 struct ifnet *ifp;
218
219 printf("%s enter\n", __FUNCTION__);
220 TAILQ_INIT(&dev_list);
221 mtx_init(&dev_mutex, "iwch dev_list lock", NULL, MTX_DEF);
222
223 err = cxio_hal_init();
224 if (err)
225 return err;
226 err = iwch_cm_init();
227 if (err)
228 return err;
229 cxio_register_ev_cb(iwch_ev_dispatch);
230
231 /* Register for ifaddr events to dynamically add TOE devs */
232 event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_event_handler,
233 NULL, EVENTHANDLER_PRI_ANY);
234
235 /* Register existing TOE interfaces by walking the ifnet chain */
236 IFNET_RLOCK();
237 VNET_LIST_RLOCK();
238 VNET_FOREACH(vnet_iter) {
239 CURVNET_SET(vnet_iter); /* XXX CURVNET_SET_QUIET() ? */
240 INIT_VNET_NET(vnet_iter);
241 TAILQ_FOREACH(ifp, &V_ifnet, if_link)
242 (void)ifaddr_event_handler(NULL, ifp);
243 CURVNET_RESTORE();
244 }
245 VNET_LIST_RUNLOCK();
246 IFNET_RUNLOCK();
247 return 0;
248}
249
250static void
251iwch_exit_module(void)
252{
253 EVENTHANDLER_DEREGISTER(ifaddr_event, event_tag);
254 cxio_unregister_ev_cb(iwch_ev_dispatch);
255 iwch_cm_term();
256 cxio_hal_exit();
257}
258
259static int
260iwch_load(module_t mod, int cmd, void *arg)
261{
262 int err = 0;
263
264 switch (cmd) {
265 case MOD_LOAD:
266 printf("Loading iw_cxgb.\n");
267
268 iwch_init_module();
269 break;
270 case MOD_QUIESCE:
271 break;
272 case MOD_UNLOAD:
273 printf("Unloading iw_cxgb.\n");
274 iwch_exit_module();
275 break;
276 case MOD_SHUTDOWN:
277 break;
278 default:
279 err = EOPNOTSUPP;
280 break;
281 }
282
283 return (err);
284}
285
286static moduledata_t mod_data = {
287 "iw_cxgb",
288 iwch_load,
289 0
290};
291
292MODULE_VERSION(iw_cxgb, 1);
293DECLARE_MODULE(iw_cxgb, mod_data, SI_SUB_EXEC, SI_ORDER_ANY);
294MODULE_DEPEND(iw_cxgb, rdma_core, 1, 1, 1);
295MODULE_DEPEND(iw_cxgb, if_cxgb, 1, 1, 1);
296MODULE_DEPEND(iw_cxgb, t3_tom, 1, 1, 1);
297