1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Basic library routines.
29 #ifdef PROPRIETARY_ELAN
30 # include <qsw/kernel.h>
32 # include <qsnet/kernel.h>
35 #undef printf /* nasty QSW #define */
37 #include <linux/config.h>
38 #include <linux/module.h>
40 #include <elan3/elanregs.h>
41 #include <elan3/elandev.h>
42 #include <elan3/elanvp.h>
43 #include <elan3/elan3mmu.h>
44 #include <elan3/elanctxt.h>
45 #include <elan3/elandebug.h>
46 #include <elan3/urom_addrs.h>
47 #include <elan3/busops.h>
48 #include <elan3/kcomm.h>
50 #include <linux/kernel.h>
52 #include <linux/string.h>
53 #include <linux/stat.h>
54 #include <linux/errno.h>
55 #include <linux/locks.h>
56 #include <linux/unistd.h>
58 #include <linux/uio.h>
60 #include <asm/system.h>
61 #include <asm/uaccess.h>
64 #include <linux/file.h>
65 #include <linux/stat.h>
66 #include <linux/list.h>
67 #include <asm/uaccess.h>
68 #include <asm/segment.h>
70 #define DEBUG_SUBSYSTEM S_QSWNAL
72 #include <linux/kp30.h>
73 #include <portals/p30.h>
74 #include <portals/lib-p30.h>
76 #define KQSW_CHECKSUM 0
78 typedef unsigned long kqsw_csum_t;
79 #define KQSW_CSUM_SIZE (2 * sizeof (kqsw_csum_t))
81 #define KQSW_CSUM_SIZE 0
83 #define KQSW_HDR_SIZE (sizeof (ptl_hdr_t) + KQSW_CSUM_SIZE)
88 #define EP_SVC_LARGE_PORTALS_SMALL (0x10) /* Portals over elan port number (large payloads) */
89 #define EP_SVC_LARGE_PORTALS_LARGE (0x11) /* Portals over elan port number (small payloads) */
90 /* NB small/large message sizes are GLOBAL constants */
93 * Performance Tuning defines
94 * NB no mention of PAGE_SIZE for interoperability
97 # define KQSW_MAXPAYLOAD (256<<10) /* biggest message this NAL will cope with */
99 # define KQSW_MAXPAYLOAD (64<<10) /* biggest message this NAL will cope with */
102 #define KQSW_SMALLPAYLOAD ((4<<10) - KQSW_HDR_SIZE) /* small/large ep receiver breakpoint */
104 #define KQSW_TX_MAXCONTIG (1<<10) /* largest payload that gets made contiguous on transmit */
106 #define KQSW_NTXMSGS 8 /* # normal transmit messages */
107 #define KQSW_NNBLK_TXMSGS 256 /* # reserved transmit messages if can't block */
109 #define KQSW_NRXMSGS_LARGE 64 /* # large receive buffers */
110 #define KQSW_EP_ENVELOPES_LARGE 128 /* # large ep envelopes */
112 #define KQSW_NRXMSGS_SMALL 256 /* # small receive buffers */
113 #define KQSW_EP_ENVELOPES_SMALL 2048 /* # small ep envelopes */
115 #define KQSW_RESCHED 100 /* # busy loops that forces scheduler to yield */
121 #define KQSW_TX_BUFFER_SIZE (KQSW_HDR_SIZE + KQSW_TX_MAXCONTIG)
122 /* The pre-allocated tx buffer (hdr + small payload) */
124 #define KQSW_NTXMSGPAGES (btopr(KQSW_TX_BUFFER_SIZE) + 1 + btopr(KQSW_MAXPAYLOAD) + 1)
125 /* Reserve elan address space for pre-allocated and pre-mapped transmit
126 * buffer and a full payload too. Extra pages allow for page alignment */
128 #define KQSW_NRXMSGPAGES_SMALL (btopr(KQSW_HDR_SIZE + KQSW_SMALLPAYLOAD))
129 /* receive hdr/payload always contiguous and page aligned */
130 #define KQSW_NRXMSGBYTES_SMALL (KQSW_NRXMSGPAGES_SMALL * PAGE_SIZE)
132 #define KQSW_NRXMSGPAGES_LARGE (btopr(KQSW_HDR_SIZE + KQSW_MAXPAYLOAD))
133 /* receive hdr/payload always contiguous and page aligned */
134 #define KQSW_NRXMSGBYTES_LARGE (KQSW_NRXMSGPAGES_LARGE * PAGE_SIZE)
135 /* biggest complete packet we can receive (or transmit) */
140 struct list_head krx_list; /* enqueue -> thread */
141 EP_RCVR *krx_eprx; /* port to post receives to */
142 EP_RXD *krx_rxd; /* receive descriptor (for repost) */
143 E3_Addr krx_elanaddr; /* Elan address of buffer (contiguous in elan vm) */
144 int krx_npages; /* # pages in receive buffer */
145 int krx_nob; /* Number Of Bytes received into buffer */
146 kpr_fwd_desc_t krx_fwd; /* embedded forwarding descriptor */
147 struct page *krx_pages[KQSW_NRXMSGPAGES_LARGE]; /* pages allocated */
148 struct iovec krx_iov[KQSW_NRXMSGPAGES_LARGE]; /* iovec for forwarding */
153 struct list_head ktx_list; /* enqueue idle/active */
154 struct list_head ktx_delayed_list; /* enqueue delayedtxds */
155 int ktx_isnblk:1; /* reserved descriptor? */
156 int ktx_forwarding:1; /* forwarding (rather than local send) */
157 uint32_t ktx_basepage; /* page offset in reserved elan tx vaddrs for mapping pages */
158 int ktx_npages; /* pages reserved for mapping messages */
159 int ktx_nmappedpages; /* # pages mapped for current message */
160 EP_IOVEC ktx_iov[EP_MAXFRAG]; /* msg frags (elan vaddrs) */
161 int ktx_niov; /* # message frags */
162 int ktx_port; /* destination ep port */
163 ptl_nid_t ktx_nid; /* destination node */
164 void *ktx_args[2]; /* completion passthru */
165 E3_Addr ktx_ebuffer; /* elan address of ktx_buffer */
166 char *ktx_buffer; /* pre-allocated contiguous buffer for hdr + small payloads */
167 unsigned long ktx_launchtime; /* when (in jiffies) the transmit was launched */
169 /* debug/info fields */
170 pid_t ktx_launcher; /* pid of launching process */
171 ptl_hdr_t *ktx_wire_hdr; /* portals header (wire endian) */
176 char kqn_init; /* what's been initialised */
177 char kqn_shuttingdown; /* I'm trying to shut down */
178 atomic_t kqn_nthreads; /* # threads still running */
180 kqswnal_rx_t *kqn_rxds; /* all the receive descriptors */
181 kqswnal_tx_t *kqn_txds; /* all the transmit descriptors */
183 struct list_head kqn_idletxds; /* transmit descriptors free to use */
184 struct list_head kqn_nblk_idletxds; /* reserved free transmit descriptors */
185 struct list_head kqn_activetxds; /* transmit descriptors being used */
186 spinlock_t kqn_idletxd_lock; /* serialise idle txd access */
187 wait_queue_head_t kqn_idletxd_waitq; /* sender blocks here waiting for idle txd */
188 struct list_head kqn_idletxd_fwdq; /* forwarded packets block here waiting for idle txd */
190 spinlock_t kqn_sched_lock; /* serialise packet schedulers */
191 wait_queue_head_t kqn_sched_waitq; /* scheduler blocks here */
193 struct list_head kqn_readyrxds; /* rxds full of data */
194 struct list_head kqn_delayedfwds; /* delayed forwards */
195 struct list_head kqn_delayedtxds; /* delayed transmits */
197 spinlock_t kqn_statelock; /* cb_cli/cb_sti */
198 nal_cb_t *kqn_cb; /* -> kqswnal_lib */
199 EP_DEV *kqn_epdev; /* elan device */
200 EP_XMTR *kqn_eptx; /* elan transmitter */
201 EP_RCVR *kqn_eprx_small; /* elan receiver (small messages) */
202 EP_RCVR *kqn_eprx_large; /* elan receiver (large messages) */
203 ELAN3_DMA_HANDLE *kqn_eptxdmahandle; /* elan reserved tx vaddrs */
204 ELAN3_DMA_HANDLE *kqn_eprxdmahandle; /* elan reserved rx vaddrs */
205 kpr_router_t kqn_router; /* connection to Kernel Portals Router module */
207 ptl_nid_t kqn_nid_offset; /* this cluster's NID offset */
208 int kqn_nnodes; /* this cluster's size */
209 int kqn_elanid; /* this nodes's elan ID */
213 #define KQN_INIT_NOTHING 0 /* MUST BE ZERO so zeroed state is initialised OK */
214 #define KQN_INIT_DATA 1
215 #define KQN_INIT_PTL 2
216 #define KQN_INIT_ALL 3
218 extern nal_cb_t kqswnal_lib;
219 extern nal_t kqswnal_api;
220 extern kqswnal_data_t kqswnal_data;
222 extern int kqswnal_thread_start (int (*fn)(void *arg), void *arg);
223 extern void kqswnal_rxhandler(EP_RXD *rxd);
224 extern int kqswnal_scheduler (void *);
225 extern void kqswnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd);
227 static inline ptl_nid_t
228 kqswnal_elanid2nid (int elanid)
230 return (kqswnal_data.kqn_nid_offset + elanid);
234 kqswnal_nid2elanid (ptl_nid_t nid)
236 /* not in this cluster? */
237 if (nid < kqswnal_data.kqn_nid_offset ||
238 nid >= kqswnal_data.kqn_nid_offset + kqswnal_data.kqn_nnodes)
241 return (nid - kqswnal_data.kqn_nid_offset);
245 kqswnal_requeue_rx (kqswnal_rx_t *krx)
247 ep_requeue_receive (krx->krx_rxd, kqswnal_rxhandler, krx,
248 krx->krx_elanaddr, krx->krx_npages * PAGE_SIZE);
252 kqswnal_pages_spanned (void *base, int nob)
254 unsigned long first_page = ((unsigned long)base) >> PAGE_SHIFT;
255 unsigned long last_page = (((unsigned long)base) + (nob - 1)) >> PAGE_SHIFT;
257 LASSERT (last_page >= first_page); /* can't wrap address space */
258 return (last_page - first_page + 1);
262 static inline kqsw_csum_t kqsw_csum (kqsw_csum_t sum, void *base, int nob)
264 unsigned char *ptr = (unsigned char *)base;
273 #endif /* _QSWNAL_H */