]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb.c
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / sys / dev / cxgb / ulp / iw_cxgb / iw_cxgb.c
1 /**************************************************************************
2
3 Copyright (c) 2007, 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 ***************************************************************************/
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
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 #define V_ifnet ifnet
59 #endif
60
61 #include <net/if.h>
62 #include <net/if_var.h>
63 #if __FreeBSD_version >= 800056
64 #include <net/vnet.h>
65 #endif
66
67 #include <netinet/in.h>
68
69 #include <contrib/rdma/ib_verbs.h>
70
71 #include <cxgb_include.h>
72 #include <ulp/iw_cxgb/iw_cxgb_wr.h>
73 #include <ulp/iw_cxgb/iw_cxgb_hal.h>
74 #include <ulp/iw_cxgb/iw_cxgb_provider.h>
75 #include <ulp/iw_cxgb/iw_cxgb_cm.h>
76 #include <ulp/iw_cxgb/iw_cxgb.h>
77
78 /*
79  * XXX :-/
80  * 
81  */
82
83 #define idr_init(x)
84
85 cxgb_cpl_handler_func t3c_handlers[NUM_CPL_CMDS];
86
87 static void open_rnic_dev(struct t3cdev *);
88 static void close_rnic_dev(struct t3cdev *);
89
90 static TAILQ_HEAD( ,iwch_dev) dev_list;
91 static struct mtx dev_mutex;
92 static eventhandler_tag event_tag;
93
94 static void
95 rnic_init(struct iwch_dev *rnicp)
96 {
97         CTR2(KTR_IW_CXGB, "%s iwch_dev %p", __FUNCTION__,  rnicp);
98         idr_init(&rnicp->cqidr);
99         idr_init(&rnicp->qpidr);
100         idr_init(&rnicp->mmidr);
101         mtx_init(&rnicp->lock, "iwch rnic lock", NULL, MTX_DEF|MTX_DUPOK);
102
103         rnicp->attr.vendor_id = 0x168;
104         rnicp->attr.vendor_part_id = 7;
105         rnicp->attr.max_qps = T3_MAX_NUM_QP - 32;
106         rnicp->attr.max_wrs = (1UL << 24) - 1;
107         rnicp->attr.max_sge_per_wr = T3_MAX_SGE;
108         rnicp->attr.max_sge_per_rdma_write_wr = T3_MAX_SGE;
109         rnicp->attr.max_cqs = T3_MAX_NUM_CQ - 1;
110         rnicp->attr.max_cqes_per_cq = (1UL << 24) - 1;
111         rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev);
112         rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE;
113         rnicp->attr.max_pds = T3_MAX_NUM_PD - 1;
114         rnicp->attr.mem_pgsizes_bitmask = 0x7FFF;       /* 4KB-128MB */
115         rnicp->attr.can_resize_wq = 0;
116         rnicp->attr.max_rdma_reads_per_qp = 8;
117         rnicp->attr.max_rdma_read_resources =
118             rnicp->attr.max_rdma_reads_per_qp * rnicp->attr.max_qps;
119         rnicp->attr.max_rdma_read_qp_depth = 8; /* IRD */
120         rnicp->attr.max_rdma_read_depth =
121             rnicp->attr.max_rdma_read_qp_depth * rnicp->attr.max_qps;
122         rnicp->attr.rq_overflow_handled = 0;
123         rnicp->attr.can_modify_ird = 0;
124         rnicp->attr.can_modify_ord = 0;
125         rnicp->attr.max_mem_windows = rnicp->attr.max_mem_regs - 1;
126         rnicp->attr.stag0_value = 1;
127         rnicp->attr.zbva_support = 1;
128         rnicp->attr.local_invalidate_fence = 1;
129         rnicp->attr.cq_overflow_detection = 1;
130         return;
131 }
132
133 static void
134 open_rnic_dev(struct t3cdev *tdev)
135 {
136         struct iwch_dev *rnicp;
137         static int vers_printed;
138
139         CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__,  tdev);
140         if (!vers_printed++)
141                 printf("Chelsio T3 RDMA Driver - version %s\n",
142                        DRV_VERSION);
143         rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp));
144         if (!rnicp) {
145                 printf("Cannot allocate ib device\n");
146                 return;
147         }
148         rnicp->rdev.ulp = rnicp;
149         rnicp->rdev.t3cdev_p = tdev;
150
151         mtx_lock(&dev_mutex);
152
153         if (cxio_rdev_open(&rnicp->rdev)) {
154                 mtx_unlock(&dev_mutex);
155                 printf("Unable to open CXIO rdev\n");
156                 ib_dealloc_device(&rnicp->ibdev);
157                 return;
158         }
159
160         rnic_init(rnicp);
161
162         TAILQ_INSERT_TAIL(&dev_list, rnicp, entry);
163         mtx_unlock(&dev_mutex);
164
165         if (iwch_register_device(rnicp)) {
166                 printf("Unable to register device\n");
167                 close_rnic_dev(tdev);
168         }
169 #ifdef notyet   
170         printf("Initialized device %s\n",
171                pci_name(rnicp->rdev.rnic_info.pdev));
172 #endif  
173         return;
174 }
175
176 static void
177 close_rnic_dev(struct t3cdev *tdev)
178 {
179         struct iwch_dev *dev, *tmp;
180         CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__,  tdev);
181         mtx_lock(&dev_mutex);
182
183         TAILQ_FOREACH_SAFE(dev, &dev_list, entry, tmp) {
184                 if (dev->rdev.t3cdev_p == tdev) {
185 #ifdef notyet                   
186                         list_del(&dev->entry);
187                         iwch_unregister_device(dev);
188                         cxio_rdev_close(&dev->rdev);
189                         idr_destroy(&dev->cqidr);
190                         idr_destroy(&dev->qpidr);
191                         idr_destroy(&dev->mmidr);
192                         ib_dealloc_device(&dev->ibdev);
193 #endif                  
194                         break;
195                 }
196         }
197         mtx_unlock(&dev_mutex);
198 }
199
200 static ifaddr_event_handler_t
201 ifaddr_event_handler(void *arg, struct ifnet *ifp)
202 {
203         printf("%s if name %s \n", __FUNCTION__, ifp->if_xname);
204         if (ifp->if_capabilities & IFCAP_TOE4) {
205                 KASSERT(T3CDEV(ifp) != NULL, ("null t3cdev ptr!"));
206                 if (cxio_hal_find_rdev_by_t3cdev(T3CDEV(ifp)) == NULL)
207                         open_rnic_dev(T3CDEV(ifp));
208         }
209         return 0;
210 }
211
212
213 static int
214 iwch_init_module(void)
215 {
216         VNET_ITERATOR_DECL(vnet_iter);
217         int err;
218         struct ifnet *ifp;
219
220         printf("%s enter\n", __FUNCTION__);
221         TAILQ_INIT(&dev_list);
222         mtx_init(&dev_mutex, "iwch dev_list lock", NULL, MTX_DEF);
223         
224         err = cxio_hal_init();
225         if (err)
226                 return err;
227         err = iwch_cm_init();
228         if (err)
229                 return err;
230         cxio_register_ev_cb(iwch_ev_dispatch);
231
232         /* Register for ifaddr events to dynamically add TOE devs */
233         event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_event_handler,
234                         NULL, EVENTHANDLER_PRI_ANY);
235
236         /* Register existing TOE interfaces by walking the ifnet chain */
237         IFNET_RLOCK();
238         VNET_LIST_RLOCK();
239         VNET_FOREACH(vnet_iter) {
240                 CURVNET_SET(vnet_iter); /* XXX CURVNET_SET_QUIET() ? */
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
250 static void
251 iwch_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
259 static int 
260 iwch_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
286 static moduledata_t mod_data = {
287         "iw_cxgb",
288         iwch_load,
289         0
290 };
291
292 MODULE_VERSION(iw_cxgb, 1);
293 DECLARE_MODULE(iw_cxgb, mod_data, SI_SUB_EXEC, SI_ORDER_ANY);
294 MODULE_DEPEND(iw_cxgb, rdma_core, 1, 1, 1);
295 MODULE_DEPEND(iw_cxgb, if_cxgb, 1, 1, 1);
296 MODULE_DEPEND(iw_cxgb, t3_tom, 1, 1, 1);
297