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