2 * Copyright (C) 2002 Cluster File Systems, Inc.
3 * Author: Eric Barton <eric@bartonsoftware.com>
5 * Copyright (C) 2002, Lawrence Livermore National Labs (LLNL)
6 * W. Marcus Miller - Based on ksocknal
8 * This file is part of Portals, http://www.sf.net/projects/lustre/
10 * Portals is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General Public
12 * License as published by the Free Software Foundation.
14 * Portals is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Portals; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 ptl_handle_ni_t kqswnal_ni;
29 kqswnal_data_t kqswnal_data;
31 kpr_nal_interface_t kqswnal_router_interface = {
34 kprni_fwd: kqswnal_fwd_packet,
35 kprni_notify: NULL, /* we're connectionless */
39 #define QSWNAL_SYSCTL 201
41 #define QSWNAL_SYSCTL_OPTIMIZED_GETS 1
42 #define QSWNAL_SYSCTL_COPY_SMALL_FWD 2
44 static ctl_table kqswnal_ctl_table[] = {
45 {QSWNAL_SYSCTL_OPTIMIZED_GETS, "optimized_gets",
46 &kqswnal_data.kqn_optimized_gets, sizeof (int),
47 0644, NULL, &proc_dointvec},
48 {QSWNAL_SYSCTL_COPY_SMALL_FWD, "copy_small_fwd",
49 &kqswnal_data.kqn_copy_small_fwd, sizeof (int),
50 0644, NULL, &proc_dointvec},
54 static ctl_table kqswnal_top_ctl_table[] = {
55 {QSWNAL_SYSCTL, "qswnal", NULL, 0, 0555, kqswnal_ctl_table},
61 kqswnal_forward(nal_t *nal,
63 void *args, size_t args_len,
64 void *ret, size_t ret_len)
66 kqswnal_data_t *k = nal->nal_data;
67 nal_cb_t *nal_cb = k->kqn_cb;
69 LASSERT (nal == &kqswnal_api);
70 LASSERT (k == &kqswnal_data);
71 LASSERT (nal_cb == &kqswnal_lib);
73 lib_dispatch(nal_cb, k, id, args, ret); /* nal needs k */
78 kqswnal_lock (nal_t *nal, unsigned long *flags)
80 kqswnal_data_t *k = nal->nal_data;
81 nal_cb_t *nal_cb = k->kqn_cb;
83 LASSERT (nal == &kqswnal_api);
84 LASSERT (k == &kqswnal_data);
85 LASSERT (nal_cb == &kqswnal_lib);
87 nal_cb->cb_cli(nal_cb,flags);
91 kqswnal_unlock(nal_t *nal, unsigned long *flags)
93 kqswnal_data_t *k = nal->nal_data;
94 nal_cb_t *nal_cb = k->kqn_cb;
96 LASSERT (nal == &kqswnal_api);
97 LASSERT (k == &kqswnal_data);
98 LASSERT (nal_cb == &kqswnal_lib);
100 nal_cb->cb_sti(nal_cb,flags);
104 kqswnal_shutdown(nal_t *nal, int ni)
106 CDEBUG (D_NET, "shutdown\n");
108 LASSERT (nal == &kqswnal_api);
113 kqswnal_yield( nal_t *nal )
115 CDEBUG (D_NET, "yield\n");
123 kqswnal_init(int interface, ptl_pt_index_t ptl_size, ptl_ac_index_t ac_size,
124 ptl_pid_t requested_pid)
126 ptl_nid_t mynid = kqswnal_elanid2nid (kqswnal_data.kqn_elanid);
127 int nnids = kqswnal_data.kqn_nnodes;
129 CDEBUG(D_NET, "calling lib_init with nid "LPX64" of %d\n", mynid, nnids);
131 lib_init(&kqswnal_lib, mynid, 0, nnids, ptl_size, ac_size);
133 return (&kqswnal_api);
137 kqswnal_get_tx_desc (struct portals_cfg *pcfg)
140 struct list_head *tmp;
142 int index = pcfg->pcfg_count;
145 spin_lock_irqsave (&kqswnal_data.kqn_idletxd_lock, flags);
147 list_for_each (tmp, &kqswnal_data.kqn_activetxds) {
151 ktx = list_entry (tmp, kqswnal_tx_t, ktx_list);
153 pcfg->pcfg_pbuf1 = (char *)ktx;
154 pcfg->pcfg_count = NTOH__u32(ktx->ktx_wire_hdr->type);
155 pcfg->pcfg_size = NTOH__u32(ktx->ktx_wire_hdr->payload_length);
156 pcfg->pcfg_nid = NTOH__u64(ktx->ktx_wire_hdr->dest_nid);
157 pcfg->pcfg_nid2 = ktx->ktx_nid;
158 pcfg->pcfg_misc = ktx->ktx_launcher;
159 pcfg->pcfg_flags = (list_empty (&ktx->ktx_delayed_list) ? 0 : 1) |
160 (!ktx->ktx_isnblk ? 0 : 2) |
161 (ktx->ktx_state << 2);
166 spin_unlock_irqrestore (&kqswnal_data.kqn_idletxd_lock, flags);
171 kqswnal_cmd (struct portals_cfg *pcfg, void *private)
173 LASSERT (pcfg != NULL);
175 switch (pcfg->pcfg_command) {
176 case NAL_CMD_GET_TXDESC:
177 return (kqswnal_get_tx_desc (pcfg));
179 case NAL_CMD_REGISTER_MYNID:
180 CDEBUG (D_IOCTL, "setting NID offset to "LPX64" (was "LPX64")\n",
181 pcfg->pcfg_nid - kqswnal_data.kqn_elanid,
182 kqswnal_data.kqn_nid_offset);
183 kqswnal_data.kqn_nid_offset =
184 pcfg->pcfg_nid - kqswnal_data.kqn_elanid;
185 kqswnal_lib.ni.nid = pcfg->pcfg_nid;
194 kqswnal_finalise (void)
199 switch (kqswnal_data.kqn_init)
206 if (kqswnal_data.kqn_sysctl != NULL)
207 unregister_sysctl_table (kqswnal_data.kqn_sysctl);
209 PORTAL_SYMBOL_UNREGISTER (kqswnal_ni);
210 kportal_nal_unregister(QSWNAL);
214 PtlNIFini (kqswnal_ni);
215 lib_fini (&kqswnal_lib);
221 case KQN_INIT_NOTHING:
225 /**********************************************************************/
226 /* Make router stop her calling me and fail any more call-ins */
227 kpr_shutdown (&kqswnal_data.kqn_router);
229 /**********************************************************************/
230 /* flag threads we've started to terminate and wait for all to ack */
232 kqswnal_data.kqn_shuttingdown = 1;
233 wake_up_all (&kqswnal_data.kqn_sched_waitq);
235 while (atomic_read (&kqswnal_data.kqn_nthreads_running) != 0) {
236 CDEBUG(D_NET, "waiting for %d threads to start shutting down\n",
237 atomic_read (&kqswnal_data.kqn_nthreads_running));
238 set_current_state (TASK_UNINTERRUPTIBLE);
239 schedule_timeout (HZ);
242 /**********************************************************************/
243 /* close elan comms */
245 if (kqswnal_data.kqn_eprx_small != NULL)
246 ep_free_rcvr (kqswnal_data.kqn_eprx_small);
248 if (kqswnal_data.kqn_eprx_large != NULL)
249 ep_free_rcvr (kqswnal_data.kqn_eprx_large);
251 if (kqswnal_data.kqn_eptx != NULL)
252 ep_free_xmtr (kqswnal_data.kqn_eptx);
254 /* freeing the xmtr completes all txs pdq */
255 LASSERT(list_empty(&kqswnal_data.kqn_activetxds));
257 if (kqswnal_data.kqn_eprx_small != NULL)
258 ep_remove_large_rcvr (kqswnal_data.kqn_eprx_small);
260 if (kqswnal_data.kqn_eprx_large != NULL)
261 ep_remove_large_rcvr (kqswnal_data.kqn_eprx_large);
263 /* wait for transmits to complete */
264 while (!list_empty(&kqswnal_data.kqn_activetxds)) {
265 CWARN("waiting for active transmits to complete\n");
266 set_current_state(TASK_UNINTERRUPTIBLE);
267 schedule_timeout(HZ);
270 if (kqswnal_data.kqn_eptx != NULL)
271 ep_free_large_xmtr (kqswnal_data.kqn_eptx);
273 /**********************************************************************/
274 /* flag threads to terminate, wake them and wait for them to die */
276 kqswnal_data.kqn_shuttingdown = 2;
277 wake_up_all (&kqswnal_data.kqn_sched_waitq);
279 while (atomic_read (&kqswnal_data.kqn_nthreads) != 0) {
280 CDEBUG(D_NET, "waiting for %d threads to terminate\n",
281 atomic_read (&kqswnal_data.kqn_nthreads));
282 set_current_state (TASK_UNINTERRUPTIBLE);
283 schedule_timeout (HZ);
286 /**********************************************************************/
287 /* No more threads. No more portals, router or comms callbacks!
288 * I control the horizontals and the verticals...
292 LASSERT (list_empty (&kqswnal_data.kqn_readyrxds));
295 /**********************************************************************/
296 /* Complete any blocked forwarding packets with error
299 while (!list_empty (&kqswnal_data.kqn_idletxd_fwdq))
301 kpr_fwd_desc_t *fwd = list_entry (kqswnal_data.kqn_idletxd_fwdq.next,
302 kpr_fwd_desc_t, kprfd_list);
303 list_del (&fwd->kprfd_list);
304 kpr_fwd_done (&kqswnal_data.kqn_router, fwd, -EHOSTUNREACH);
307 while (!list_empty (&kqswnal_data.kqn_delayedfwds))
309 kpr_fwd_desc_t *fwd = list_entry (kqswnal_data.kqn_delayedfwds.next,
310 kpr_fwd_desc_t, kprfd_list);
311 list_del (&fwd->kprfd_list);
312 kpr_fwd_done (&kqswnal_data.kqn_router, fwd, -EHOSTUNREACH);
315 /**********************************************************************/
316 /* Wait for router to complete any packets I sent her
319 kpr_deregister (&kqswnal_data.kqn_router);
322 /**********************************************************************/
323 /* Unmap message buffers and free all descriptors and buffers
327 /* FTTB, we need to unmap any remaining mapped memory. When
328 * ep_dvma_release() get fixed (and releases any mappings in the
329 * region), we can delete all the code from here --------> */
331 for (ktx = kqswnal_data.kqn_txds; ktx != NULL; ktx =ktx->ktx_alloclist){
332 /* If ktx has a buffer, it got mapped; unmap now. NB only
333 * the pre-mapped stuff is still mapped since all tx descs
336 if (ktx->ktx_buffer != NULL)
337 ep_dvma_unload(kqswnal_data.kqn_ep,
338 kqswnal_data.kqn_ep_tx_nmh,
342 for (krx = kqswnal_data.kqn_rxds; krx != NULL; krx =krx->krx_alloclist){
343 /* If krx_kiov[0].kiov_page got allocated, it got mapped.
344 * NB subsequent pages get merged */
346 if (krx->krx_kiov[0].kiov_page != NULL)
347 ep_dvma_unload(kqswnal_data.kqn_ep,
348 kqswnal_data.kqn_ep_rx_nmh,
349 &krx->krx_elanbuffer);
351 /* <----------- to here */
353 if (kqswnal_data.kqn_ep_rx_nmh != NULL)
354 ep_dvma_release(kqswnal_data.kqn_ep,kqswnal_data.kqn_ep_rx_nmh);
356 if (kqswnal_data.kqn_ep_tx_nmh != NULL)
357 ep_dvma_release(kqswnal_data.kqn_ep,kqswnal_data.kqn_ep_tx_nmh);
359 if (kqswnal_data.kqn_eprxdmahandle != NULL)
361 elan3_dvma_unload(kqswnal_data.kqn_ep->DmaState,
362 kqswnal_data.kqn_eprxdmahandle, 0,
363 KQSW_NRXMSGPAGES_SMALL * KQSW_NRXMSGS_SMALL +
364 KQSW_NRXMSGPAGES_LARGE * KQSW_NRXMSGS_LARGE);
366 elan3_dma_release(kqswnal_data.kqn_ep->DmaState,
367 kqswnal_data.kqn_eprxdmahandle);
370 if (kqswnal_data.kqn_eptxdmahandle != NULL)
372 elan3_dvma_unload(kqswnal_data.kqn_ep->DmaState,
373 kqswnal_data.kqn_eptxdmahandle, 0,
374 KQSW_NTXMSGPAGES * (KQSW_NTXMSGS +
377 elan3_dma_release(kqswnal_data.kqn_ep->DmaState,
378 kqswnal_data.kqn_eptxdmahandle);
382 while (kqswnal_data.kqn_txds != NULL) {
383 ktx = kqswnal_data.kqn_txds;
385 if (ktx->ktx_buffer != NULL)
386 PORTAL_FREE(ktx->ktx_buffer, KQSW_TX_BUFFER_SIZE);
388 kqswnal_data.kqn_txds = ktx->ktx_alloclist;
389 PORTAL_FREE(ktx, sizeof(*ktx));
392 while (kqswnal_data.kqn_rxds != NULL) {
395 krx = kqswnal_data.kqn_rxds;
396 for (i = 0; i < krx->krx_npages; i++)
397 if (krx->krx_kiov[i].kiov_page != NULL)
398 __free_page (krx->krx_kiov[i].kiov_page);
400 kqswnal_data.kqn_rxds = krx->krx_alloclist;
401 PORTAL_FREE(krx, sizeof (*krx));
404 /* resets flags, pointers to NULL etc */
405 memset(&kqswnal_data, 0, sizeof (kqswnal_data));
407 CDEBUG (D_MALLOC, "done kmem %d\n", atomic_read(&portal_kmemory));
409 printk (KERN_INFO "Lustre: Routing QSW NAL unloaded (final mem %d)\n",
410 atomic_read(&portal_kmemory));
414 kqswnal_initialise (void)
417 EP_RAILMASK all_rails = EP_RAILMASK_ALL;
419 ELAN3_DMA_REQUEST dmareq;
426 int pkmem = atomic_read(&portal_kmemory);
428 LASSERT (kqswnal_data.kqn_init == KQN_INIT_NOTHING);
430 CDEBUG (D_MALLOC, "start kmem %d\n", atomic_read(&portal_kmemory));
432 kqswnal_api.forward = kqswnal_forward;
433 kqswnal_api.shutdown = kqswnal_shutdown;
434 kqswnal_api.yield = kqswnal_yield;
435 kqswnal_api.validate = NULL; /* our api validate is a NOOP */
436 kqswnal_api.lock = kqswnal_lock;
437 kqswnal_api.unlock = kqswnal_unlock;
438 kqswnal_api.nal_data = &kqswnal_data;
440 kqswnal_lib.nal_data = &kqswnal_data;
442 memset(&kqswnal_rpc_success, 0, sizeof(kqswnal_rpc_success));
443 memset(&kqswnal_rpc_failed, 0, sizeof(kqswnal_rpc_failed));
445 kqswnal_rpc_failed.Data[0] = -ECONNREFUSED;
447 kqswnal_rpc_failed.Status = -ECONNREFUSED;
449 /* ensure all pointers NULL etc */
450 memset (&kqswnal_data, 0, sizeof (kqswnal_data));
452 kqswnal_data.kqn_optimized_gets = KQSW_OPTIMIZED_GETS;
453 kqswnal_data.kqn_copy_small_fwd = KQSW_COPY_SMALL_FWD;
455 kqswnal_data.kqn_cb = &kqswnal_lib;
457 INIT_LIST_HEAD (&kqswnal_data.kqn_idletxds);
458 INIT_LIST_HEAD (&kqswnal_data.kqn_nblk_idletxds);
459 INIT_LIST_HEAD (&kqswnal_data.kqn_activetxds);
460 spin_lock_init (&kqswnal_data.kqn_idletxd_lock);
461 init_waitqueue_head (&kqswnal_data.kqn_idletxd_waitq);
462 INIT_LIST_HEAD (&kqswnal_data.kqn_idletxd_fwdq);
464 INIT_LIST_HEAD (&kqswnal_data.kqn_delayedfwds);
465 INIT_LIST_HEAD (&kqswnal_data.kqn_delayedtxds);
466 INIT_LIST_HEAD (&kqswnal_data.kqn_readyrxds);
468 spin_lock_init (&kqswnal_data.kqn_sched_lock);
469 init_waitqueue_head (&kqswnal_data.kqn_sched_waitq);
471 spin_lock_init (&kqswnal_data.kqn_statelock);
473 /* pointers/lists/locks initialised */
474 kqswnal_data.kqn_init = KQN_INIT_DATA;
477 kqswnal_data.kqn_ep = ep_system();
478 if (kqswnal_data.kqn_ep == NULL) {
479 CERROR("Can't initialise EKC\n");
483 if (ep_waitfor_nodeid(kqswnal_data.kqn_ep) == ELAN_INVALID_NODE) {
484 CERROR("Can't get elan ID\n");
489 /**********************************************************************/
490 /* Find the first Elan device */
492 kqswnal_data.kqn_ep = ep_device (0);
493 if (kqswnal_data.kqn_ep == NULL)
495 CERROR ("Can't get elan device 0\n");
500 kqswnal_data.kqn_nid_offset = 0;
501 kqswnal_data.kqn_nnodes = ep_numnodes (kqswnal_data.kqn_ep);
502 kqswnal_data.kqn_elanid = ep_nodeid (kqswnal_data.kqn_ep);
504 /**********************************************************************/
505 /* Get the transmitter */
507 kqswnal_data.kqn_eptx = ep_alloc_xmtr (kqswnal_data.kqn_ep);
508 if (kqswnal_data.kqn_eptx == NULL)
510 CERROR ("Can't allocate transmitter\n");
515 /**********************************************************************/
516 /* Get the receivers */
518 kqswnal_data.kqn_eprx_small = ep_alloc_rcvr (kqswnal_data.kqn_ep,
519 EP_MSG_SVC_PORTALS_SMALL,
520 KQSW_EP_ENVELOPES_SMALL);
521 if (kqswnal_data.kqn_eprx_small == NULL)
523 CERROR ("Can't install small msg receiver\n");
528 kqswnal_data.kqn_eprx_large = ep_alloc_rcvr (kqswnal_data.kqn_ep,
529 EP_MSG_SVC_PORTALS_LARGE,
530 KQSW_EP_ENVELOPES_LARGE);
531 if (kqswnal_data.kqn_eprx_large == NULL)
533 CERROR ("Can't install large msg receiver\n");
538 /**********************************************************************/
539 /* Reserve Elan address space for transmit descriptors NB we may
540 * either send the contents of associated buffers immediately, or
541 * map them for the peer to suck/blow... */
543 kqswnal_data.kqn_ep_tx_nmh =
544 ep_dvma_reserve(kqswnal_data.kqn_ep,
545 KQSW_NTXMSGPAGES*(KQSW_NTXMSGS+KQSW_NNBLK_TXMSGS),
547 if (kqswnal_data.kqn_ep_tx_nmh == NULL) {
548 CERROR("Can't reserve tx dma space\n");
553 dmareq.Waitfn = DDI_DMA_SLEEP;
554 dmareq.ElanAddr = (E3_Addr) 0;
555 dmareq.Attr = PTE_LOAD_LITTLE_ENDIAN;
556 dmareq.Perm = ELAN_PERM_REMOTEWRITE;
558 rc = elan3_dma_reserve(kqswnal_data.kqn_ep->DmaState,
559 KQSW_NTXMSGPAGES*(KQSW_NTXMSGS+KQSW_NNBLK_TXMSGS),
560 &dmareq, &kqswnal_data.kqn_eptxdmahandle);
561 if (rc != DDI_SUCCESS)
563 CERROR ("Can't reserve rx dma space\n");
568 /**********************************************************************/
569 /* Reserve Elan address space for receive buffers */
571 kqswnal_data.kqn_ep_rx_nmh =
572 ep_dvma_reserve(kqswnal_data.kqn_ep,
573 KQSW_NRXMSGPAGES_SMALL * KQSW_NRXMSGS_SMALL +
574 KQSW_NRXMSGPAGES_LARGE * KQSW_NRXMSGS_LARGE,
576 if (kqswnal_data.kqn_ep_tx_nmh == NULL) {
577 CERROR("Can't reserve rx dma space\n");
582 dmareq.Waitfn = DDI_DMA_SLEEP;
583 dmareq.ElanAddr = (E3_Addr) 0;
584 dmareq.Attr = PTE_LOAD_LITTLE_ENDIAN;
585 dmareq.Perm = ELAN_PERM_REMOTEWRITE;
587 rc = elan3_dma_reserve (kqswnal_data.kqn_ep->DmaState,
588 KQSW_NRXMSGPAGES_SMALL * KQSW_NRXMSGS_SMALL +
589 KQSW_NRXMSGPAGES_LARGE * KQSW_NRXMSGS_LARGE,
590 &dmareq, &kqswnal_data.kqn_eprxdmahandle);
591 if (rc != DDI_SUCCESS)
593 CERROR ("Can't reserve rx dma space\n");
598 /**********************************************************************/
599 /* Allocate/Initialise transmit descriptors */
601 kqswnal_data.kqn_txds = NULL;
602 for (i = 0; i < (KQSW_NTXMSGS + KQSW_NNBLK_TXMSGS); i++)
605 int basepage = i * KQSW_NTXMSGPAGES;
607 PORTAL_ALLOC (ktx, sizeof(*ktx));
613 ktx->ktx_alloclist = kqswnal_data.kqn_txds;
614 kqswnal_data.kqn_txds = ktx;
616 PORTAL_ALLOC (ktx->ktx_buffer, KQSW_TX_BUFFER_SIZE);
617 if (ktx->ktx_buffer == NULL)
623 /* Map pre-allocated buffer NOW, to save latency on transmit */
624 premapped_pages = kqswnal_pages_spanned(ktx->ktx_buffer,
625 KQSW_TX_BUFFER_SIZE);
627 ep_dvma_load(kqswnal_data.kqn_ep, NULL,
628 ktx->ktx_buffer, KQSW_TX_BUFFER_SIZE,
629 kqswnal_data.kqn_ep_tx_nmh, basepage,
630 &all_rails, &ktx->ktx_ebuffer);
632 elan3_dvma_kaddr_load (kqswnal_data.kqn_ep->DmaState,
633 kqswnal_data.kqn_eptxdmahandle,
634 ktx->ktx_buffer, KQSW_TX_BUFFER_SIZE,
635 basepage, &ktx->ktx_ebuffer);
637 ktx->ktx_basepage = basepage + premapped_pages; /* message mapping starts here */
638 ktx->ktx_npages = KQSW_NTXMSGPAGES - premapped_pages; /* for this many pages */
640 INIT_LIST_HEAD (&ktx->ktx_delayed_list);
642 ktx->ktx_state = KTX_IDLE;
643 ktx->ktx_isnblk = (i >= KQSW_NTXMSGS);
644 list_add_tail (&ktx->ktx_list,
645 ktx->ktx_isnblk ? &kqswnal_data.kqn_nblk_idletxds :
646 &kqswnal_data.kqn_idletxds);
649 /**********************************************************************/
650 /* Allocate/Initialise receive descriptors */
652 kqswnal_data.kqn_rxds = NULL;
654 for (i = 0; i < KQSW_NRXMSGS_SMALL + KQSW_NRXMSGS_LARGE; i++)
663 PORTAL_ALLOC(krx, sizeof(*krx));
669 krx->krx_alloclist = kqswnal_data.kqn_rxds;
670 kqswnal_data.kqn_rxds = krx;
672 if (i < KQSW_NRXMSGS_SMALL)
674 krx->krx_npages = KQSW_NRXMSGPAGES_SMALL;
675 krx->krx_eprx = kqswnal_data.kqn_eprx_small;
679 krx->krx_npages = KQSW_NRXMSGPAGES_LARGE;
680 krx->krx_eprx = kqswnal_data.kqn_eprx_large;
683 LASSERT (krx->krx_npages > 0);
684 for (j = 0; j < krx->krx_npages; j++)
686 struct page *page = alloc_page(GFP_KERNEL);
693 krx->krx_kiov[j].kiov_page = page;
694 LASSERT(page_address(page) != NULL);
697 ep_dvma_load(kqswnal_data.kqn_ep, NULL,
699 PAGE_SIZE, kqswnal_data.kqn_ep_rx_nmh,
700 elan_page_idx, &all_rails, &elanbuffer);
703 krx->krx_elanbuffer = elanbuffer;
705 rc = ep_nmd_merge(&krx->krx_elanbuffer,
706 &krx->krx_elanbuffer,
708 /* NB contiguous mapping */
712 elan3_dvma_kaddr_load(kqswnal_data.kqn_ep->DmaState,
713 kqswnal_data.kqn_eprxdmahandle,
715 PAGE_SIZE, elan_page_idx,
718 krx->krx_elanbuffer = elanbuffer;
720 /* NB contiguous mapping */
721 LASSERT (elanbuffer == krx->krx_elanbuffer + j * PAGE_SIZE);
727 LASSERT (elan_page_idx ==
728 (KQSW_NRXMSGS_SMALL * KQSW_NRXMSGPAGES_SMALL) +
729 (KQSW_NRXMSGS_LARGE * KQSW_NRXMSGPAGES_LARGE));
731 /**********************************************************************/
732 /* Network interface ready to initialise */
734 rc = PtlNIInit(kqswnal_init, 32, 4, 0, &kqswnal_ni);
737 CERROR ("PtlNIInit failed %d\n", rc);
742 kqswnal_data.kqn_init = KQN_INIT_PTL;
744 /**********************************************************************/
745 /* Queue receives, now that it's OK to run their completion callbacks */
747 for (krx = kqswnal_data.kqn_rxds; krx != NULL; krx =krx->krx_alloclist){
748 /* NB this enqueue can allocate/sleep (attr == 0) */
750 rc = ep_queue_receive(krx->krx_eprx, kqswnal_rxhandler, krx,
751 &krx->krx_elanbuffer, 0);
753 rc = ep_queue_receive(krx->krx_eprx, kqswnal_rxhandler, krx,
755 krx->krx_npages * PAGE_SIZE, 0);
757 if (rc != EP_SUCCESS)
759 CERROR ("failed ep_queue_receive %d\n", rc);
765 /**********************************************************************/
766 /* Spawn scheduling threads */
767 for (i = 0; i < num_online_cpus(); i++) {
768 rc = kqswnal_thread_start (kqswnal_scheduler, NULL);
771 CERROR ("failed to spawn scheduling thread: %d\n", rc);
777 /**********************************************************************/
778 /* Connect to the router */
779 rc = kpr_register (&kqswnal_data.kqn_router, &kqswnal_router_interface);
780 CDEBUG(D_NET, "Can't initialise routing interface (rc = %d): not routing\n",rc);
782 rc = kportal_nal_register (QSWNAL, &kqswnal_cmd, NULL);
784 CERROR ("Can't initialise command interface (rc = %d)\n", rc);
790 /* Press on regardless even if registering sysctl doesn't work */
791 kqswnal_data.kqn_sysctl = register_sysctl_table (kqswnal_top_ctl_table, 0);
794 PORTAL_SYMBOL_REGISTER(kqswnal_ni);
795 kqswnal_data.kqn_init = KQN_INIT_ALL;
797 printk(KERN_INFO "Lustre: Routing QSW NAL loaded on node %d of %d "
798 "(Routing %s, initial mem %d)\n",
799 kqswnal_data.kqn_elanid, kqswnal_data.kqn_nnodes,
800 kpr_routing (&kqswnal_data.kqn_router) ? "enabled" : "disabled",
807 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
808 MODULE_DESCRIPTION("Kernel Quadrics/Elan NAL v1.01");
809 MODULE_LICENSE("GPL");
811 module_init (kqswnal_initialise);
812 module_exit (kqswnal_finalise);
814 EXPORT_SYMBOL (kqswnal_ni);