1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Based on ksocknal and qswnal
6 * Copyright (C) 2002 Cluster File Systems, Inc.
7 * Author: Robert Read <rread@datarithm.net>
9 * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
11 * Portals is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Portals is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Portals; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 ptl_handle_ni_t kgmnal_ni;
30 kgmnal_data_t kgmnal_data;
33 kpr_nal_interface_t kqswnal_router_interface = {
36 kprni_fwd: kgmnal_fwd_packet,
39 static int kgmnal_forward(nal_t *nal,
41 void *args, size_t args_len,
42 void *ret, size_t ret_len)
44 kgmnal_data_t *k = nal->nal_data;
45 nal_cb_t *nal_cb = k->kgm_cb;
47 LASSERT (nal == &kgmnal_api);
48 LASSERT (k == &kgmnal_data);
49 LASSERT (nal_cb == &kgmnal_lib);
51 lib_dispatch(nal_cb, k, id, args, ret); /* nal needs k */
55 static void kgmnal_lock(nal_t *nal, unsigned long *flags)
57 kgmnal_data_t *k = nal->nal_data;
58 nal_cb_t *nal_cb = k->kgm_cb;
61 LASSERT (nal == &kgmnal_api);
62 LASSERT (k == &kgmnal_data);
63 LASSERT (nal_cb == &kgmnal_lib);
65 nal_cb->cb_cli(nal_cb,flags);
68 static void kgmnal_unlock(nal_t *nal, unsigned long *flags)
70 kgmnal_data_t *k = nal->nal_data;
71 nal_cb_t *nal_cb = k->kgm_cb;
74 LASSERT (nal == &kgmnal_api);
75 LASSERT (k == &kgmnal_data);
76 LASSERT (nal_cb == &kgmnal_lib);
78 nal_cb->cb_sti(nal_cb,flags);
81 static int kgmnal_shutdown(nal_t *nal, int ni)
83 LASSERT (nal == &kgmnal_api);
87 static void kgmnal_yield( nal_t *nal )
89 LASSERT (nal == &kgmnal_api);
91 if (current->need_resched)
96 kgmnal_rx_t *kgm_add_recv(kgmnal_data_t *data,int ndx)
100 PORTAL_ALLOC(conn, sizeof(kgmnal_rx_t));
101 /* Check for out of mem here */
103 printk("kgm_add_recv: memory alloc failed\n");
107 list_add(&conn->krx_item,(struct list_head *)&data->kgm_list);
109 // conn->len=conn->ptlhdr_copied=0;
114 static nal_t *kgmnal_init(int interface, ptl_pt_index_t ptl_size,
115 ptl_ac_index_t ac_size, ptl_pid_t requested_pid)
119 gm_max_node_id_in_use(kgmnal_data.kgm_port, &nnids);
121 CDEBUG(D_NET, "calling lib_init with nid 0x%Lx of %d\n",
122 kgmnal_data.kgm_nid, nnids);
123 lib_init(&kgmnal_lib, kgmnal_data.kgm_nid, 0, nnids,ptl_size, ac_size);
128 kgmnal_finalize(void)
130 struct list_head *tmp;
132 PORTAL_SYMBOL_UNREGISTER (kgmnal_ni);
133 PtlNIFini(kgmnal_ni);
134 lib_fini(&kgmnal_api);
136 if (kgmnal_data.kgm_port) {
137 gm_close(kgmnal_data.kgm_port);
140 /* FIXME: free dma buffers */
141 /* FIXME: kill receiver thread */
143 PORTAL_FREE (kgmnal_data.kgm_trans, bsizeof(kgmnal_tx_t)*TXMSGS);
145 list_for_each(tmp, &kgmnal_data.kgm_list) {
147 conn = list_entry(tmp, kgmnal_rx_t, krx_item);
148 CDEBUG(D_IOCTL, "freeing conn %p\n",conn);
150 list_del(&conn->krx_item);
151 PORTAL_FREE(conn, sizeof(*conn));
154 CDEBUG (D_MALLOC, "done kmem %d\n", atomic_read (&portal_kmemory));
160 kgmnal_initialize(void)
164 unsigned long sizemask;
167 CDEBUG (D_MALLOC, "start kmem %d\n", atomic_read (&portal_kmemory));
169 kgmnal_api.forward = kgmnal_forward;
170 kgmnal_api.shutdown = kgmnal_shutdown;
171 kgmnal_api.yield = kgmnal_yield;
172 kgmnal_api.validate = NULL; /* our api validate is a NOOP */
173 kgmnal_api.lock= kgmnal_lock;
174 kgmnal_api.unlock= kgmnal_unlock;
175 kgmnal_api.nal_data = &kgmnal_data;
177 kgmnal_lib.nal_data = &kgmnal_data;
179 memset(&kgmnal_data, 0, sizeof(kgmnal_data));
181 INIT_LIST_HEAD(&kgmnal_data.kgm_list);
182 kgmnal_data.kgm_cb = &kgmnal_lib;
184 /* Allocate transmit descriptors */
185 PORTAL_ALLOC (kgmnal_data.kgm_trans, sizeof(kgmnal_tx_t)*TXMSGS);
186 if (kgmnal_data.kgm_trans==NULL) {
187 printk("kgmnal: init: failed to allocate transmit "
191 memset(kgmnal_data.kgm_trans,-1,sizeof(kgmnal_tx_t)*(TXMSGS));
193 spin_lock_init(&kgmnal_data.kgm_dispatch_lock);
194 spin_lock_init(&kgmnal_data.kgm_update_lock);
195 spin_lock_init(&kgmnal_data.kgm_send_lock);
197 /* Do the receiver and xmtr allocation */
200 if (rc != GM_SUCCESS) {
201 CERROR("gm_init failed: %d\n", rc);
205 rc = gm_open(&kgmnal_data.kgm_port, 0 , KGM_PORT_NUM, KGM_HOSTNAME,
207 if (rc != GM_SUCCESS) {
209 kgmnal_data.kgm_port = NULL;
210 CERROR("gm_open failed: %d\n", rc);
213 gm_get_node_id(kgmnal_data.kgm_port, &nid);
214 kgmnal_data.kgm_nid = nid;
215 /* Allocate 2 different sizes of buffers. For new, use half
216 the tokens for each. */
217 ntok = gm_num_receive_tokens(kgmnal_data.kgm_port)/2;
218 CDEBUG(D_NET, "gmnal_init: creating %d large %d byte recv buffers\n",
219 ntok, MSG_LEN_LARGE);
221 void * buffer = gm_dma_malloc(kgmnal_data.kgm_port,
223 if (buffer == NULL) {
224 CERROR("gm_init failed: %d\n", rc);
227 CDEBUG(D_NET, " add buffer: port %p buf %p len %d size %d "
228 "pri %d\n ", kgmnal_data.kgm_port, buffer,
229 MSG_LEN_LARGE, MSG_SIZE_LARGE, GM_LOW_PRIORITY);
231 gm_provide_receive_buffer(kgmnal_data.kgm_port, buffer,
232 MSG_SIZE_LARGE, GM_LOW_PRIORITY);
235 ntok = gm_num_receive_tokens(kgmnal_data.kgm_port)/2;
236 CDEBUG(D_NET, "gmnal_init: creating %d small %d byte recv buffers\n",
237 ntok, MSG_LEN_SMALL);
239 void * buffer = gm_dma_malloc(kgmnal_data.kgm_port,
241 if (buffer == NULL) {
242 CERROR("gm_init failed: %d\n", rc);
245 CDEBUG(D_NET, " add buffer: port %p buf %p len %d size %d "
246 "pri %d\n ", kgmnal_data.kgm_port, buffer,
247 MSG_LEN_SMALL, MSG_SIZE_SMALL, GM_LOW_PRIORITY);
249 gm_provide_receive_buffer(kgmnal_data.kgm_port, buffer,
250 MSG_SIZE_SMALL, GM_LOW_PRIORITY);
253 sizemask = (1 << MSG_SIZE_LARGE) | (1 << MSG_SIZE_SMALL);
254 CDEBUG(D_NET, "gm_set_acceptable_sizes port %p pri %d mask 0x%x\n",
255 kgmnal_data.kgm_port, GM_LOW_PRIORITY, sizemask);
256 gm_set_acceptable_sizes(kgmnal_data.kgm_port, GM_LOW_PRIORITY,
258 gm_set_acceptable_sizes(kgmnal_data.kgm_port, GM_HIGH_PRIORITY, 0);
260 /* Initialize Network Interface */
261 rc = PtlNIInit(kgmnal_init, 32, 4, 0, &kgmnal_ni);
263 CERROR("PtlNIInit failed %d\n", rc);
267 /* Start receiver thread */
268 kernel_thread(kgmnal_recv_thread, &kgmnal_data, 0);
270 PORTAL_SYMBOL_REGISTER(kgmnal_ni);
272 kgmnal_data.kgm_init = 1;
277 MODULE_AUTHOR("Robert Read <rread@datarithm.net>");
278 MODULE_DESCRIPTION("Kernel Myrinet GM NAL v0.1");
279 MODULE_LICENSE("GPL");
281 module_init (kgmnal_initialize);
282 module_exit (kgmnal_finalize);
284 EXPORT_SYMBOL (kgmnal_ni);