Whamcloud - gitweb
50ef0b8d9215a56ddec3fcceb2e60b8823ae2a66
[fs/lustre-release.git] / lnet / klnds / gnilnd / gnilnd_aries.h
1 /*
2  * Copyright (C) 2009-2012 Cray, Inc.
3  *
4  * Copyright (c) 2014, Intel Corporation.
5  *
6  *   Author: Nic Henke <nic@cray.com>, James Shimek <jshimek@cray.com>
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre 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.
13  *
14  *   Lustre 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.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with Lustre; if not, write to the Free Software
21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  */
24 #ifndef _GNILND_ARIES_H
25 #define _GNILND_ARIES_H
26
27 /* for lnet_ipif_query */
28 #include <lnet/lib-lnet.h>
29
30 #ifndef _GNILND_HSS_OPS_H
31 # error "must include gnilnd_hss_ops.h first"
32 #endif
33
34 /* Set HW related values */
35 #ifdef CONFIG_CRAY_XT
36 #include <aries/aries_timeouts_gpl.h>
37 #else
38 /* from aries_timeouts_gpl.h when building for generic kernel */
39 #define TIMEOUT_SECS(x)         ((uint64_t)(((x) / 1000.0) + 0.5))
40 #ifndef TO_GNILND_timeout
41 #define TO_GNILND_timeout               (60000.000000)
42 #endif /* TO_GNILND_timeout */
43 #endif /* CONFIG_CRAY_XT */
44
45 #define GNILND_BASE_TIMEOUT        TIMEOUT_SECS(TO_GNILND_timeout)
46 #define GNILND_CHECKSUM_DEFAULT    0            /* all off for Aries */
47
48 #if defined(CONFIG_CRAY_COMPUTE)
49 #define GNILND_REVERSE_RDMA        GNILND_REVERSE_PUT
50 #define GNILND_RDMA_DLVR_OPTION    GNI_DLVMODE_PERFORMANCE
51 #else
52 #define GNILND_REVERSE_RDMA        GNILND_REVERSE_GET
53 #define GNILND_RDMA_DLVR_OPTION    GNI_DLVMODE_PERFORMANCE
54 #define GNILND_SCHED_THREADS       7             /* scheduler threads */
55 #endif
56
57 /* Thread-safe kgni implemented in minor ver 45, code rev 0xb9 */
58 #define GNILND_KGNI_TS_MINOR_VER 0x45
59 #define GNILND_TS_ENABLE         1
60
61 /* plug in our functions for use on the simulator */
62 #if !defined(GNILND_USE_RCA)
63
64 extern kgn_data_t kgnilnd_data;
65
66 #define kgnilnd_hw_hb()              do {} while(0)
67
68 #ifdef CONFIG_CRAY_XT
69
70 /* Aries Sim doesn't have hardcoded tables, so we'll hijack the nic_pe
71  * and decode our address and nic addr from that - the rest are just offsets */
72
73 static inline int
74 kgnilnd_nid_to_nicaddrs(__u32 nid, int numnic, __u32 *nicaddr)
75 {
76         if (numnic > 1) {
77                 CERROR("manual nid2nic translation doesn't support"
78                        "multiple nic addrs (you asked for %d)\n",
79                         numnic);
80                 return -EINVAL;
81         }
82         if (nid < kgnilnd_data.kgn_nid_trans_private) {
83                 CERROR("Request for invalid nid translation %u,"
84                        "minimum "LPU64"\n",
85                        nid, kgnilnd_data.kgn_nid_trans_private);
86                 return -ESRCH;
87         }
88
89         *nicaddr = nid - kgnilnd_data.kgn_nid_trans_private;
90
91         CDEBUG(D_NETTRACE, "Sim nid %d -> nic 0x%x\n", nid, *nicaddr);
92
93         return 1;
94 }
95
96 static inline int
97 kgnilnd_nicaddr_to_nid(__u32 nicaddr, __u32 *nid)
98 {
99         *nid = kgnilnd_data.kgn_nid_trans_private + nicaddr;
100         return 1;
101 }
102
103 /* XXX Nic: This does not support multiple device!!!! */
104 static inline int
105 kgnilnd_setup_nic_translation(__u32 device_id)
106 {
107         char              *if_name = "ipogif0";
108         __u32              ipaddr, netmask, my_nid;
109         int                up, rc;
110
111         LCONSOLE_INFO("using Aries SIM IP info for RCA translation\n");
112
113         rc = lnet_ipif_query(if_name, &up, &ipaddr, &netmask);
114         if (rc != 0) {
115                 CERROR ("can't get IP interface for %s: %d\n", if_name, rc);
116                 return rc;
117         }
118         if (!up) {
119                 CERROR ("IP interface %s is down\n", if_name);
120                 return -ENODEV;
121         }
122
123         my_nid = ((ipaddr >> 8) & 0xFF) + (ipaddr & 0xFF);
124         kgnilnd_data.kgn_nid_trans_private = my_nid - device_id;
125
126         return 0;
127 }
128
129 #else /* CONFIG_CRAY_XT */
130 #include <net/inet_common.h>
131 #include <linux/if_arp.h>
132
133 static inline int
134 kgnilnd_nid_to_nicaddrs(__u32 nid, int numnic, __u32 *nicaddrs)
135 {
136         int rc;
137
138 #define NID_MASK ((1ULL << 18) - 1)
139         mm_segment_t fs;
140         struct arpreq req = {
141                 .arp_dev = "ipogif0",
142         };
143
144         req.arp_pa.sa_family = AF_INET;
145         ((struct sockaddr_in *)&req.arp_pa)->sin_addr.s_addr = htonl(nid);
146
147         fs = get_fs();
148         set_fs(get_ds());
149
150         rc = inet_ioctl(kgnilnd_data.kgn_sock, SIOCGARP, (unsigned long)&req);
151         set_fs(fs);
152
153         if (rc < 0) {
154                 CDEBUG(D_NETERROR, "inet_ioctl returned %d\n", rc);
155                 return 0;
156         }
157
158         /* use the lower 18 bits of the mac address to use as a nid value */
159         *nicaddrs = *(__u32 *)&req.arp_ha.sa_data[2];
160         *nicaddrs = ntohl(*nicaddrs) & NID_MASK;
161
162         CDEBUG(D_NETTRACE, "nid %s -> nic 0x%x\n", libcfs_nid2str(nid),
163                 nicaddrs[0]);
164
165         return 1;
166 }
167
168 static inline int
169 kgnilnd_nicaddr_to_nid(__u32 nicaddr, __u32 *nid)
170 {
171         int rc;
172         mm_segment_t fs;
173         struct ifreq ifr = {
174                 .ifr_name = "ipogif0",
175         };
176
177         struct sockaddr_in* ipaddr = (struct sockaddr_in*)&ifr.ifr_addr;
178
179         fs = get_fs();
180         set_fs(get_ds());
181         rc = inet_ioctl(kgnilnd_data.kgn_sock, SIOCGIFADDR, (unsigned long)&ifr);
182         set_fs(fs);
183
184         if (rc < 0) {
185                 CDEBUG(D_NETERROR, "inet_ioctl returned %d\n", rc);
186                 return 1;
187         }
188
189         CDEBUG(D_NETTRACE, "ipaddr %08x\n", htonl(ipaddr->sin_addr.s_addr));
190
191         *nid = htonl(ipaddr->sin_addr.s_addr);
192         CDEBUG(D_NETTRACE, "nic 0x%x -> nid %s\n", nicaddr,
193                 libcfs_nid2str(*nid));
194         return 0;
195 }
196
197 static inline int
198 kgnilnd_setup_nic_translation(__u32 device_id)
199 {
200         return 0;
201 }
202
203 #endif /* CONFIG_CRAY_XT */
204
205 #endif /* GNILND_USE_RCA */
206
207 #endif /* _GNILND_ARIES_H */