Commit patch to Inifiniband support and additional support information
[etherboot.git] / src / drivers / net / mlx_ipoib / ib_driver.c
1 /*
2   This software is available to you under a choice of one of two
3   licenses.  You may choose to be licensed under the terms of the GNU
4   General Public License (GPL) Version 2, available at
5   <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
6   license, available in the LICENSE.TXT file accompanying this
7   software.  These details are also available at
8   <http://openib.org/license.html>.
9
10   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   SOFTWARE.
18
19   Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
20 */
21
22 #include "ib_driver.h"
23
24 static const __u8 ipv4_bcast_gid[] = {
25         0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
26         0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
27 };
28
29 static int wait_logic_link_up(__u8 port)
30 {
31         unsigned int relax_time, max_time;
32         relax_time = 500;
33         max_time = 30000;       /* 30 seconds */
34         int rc;
35         unsigned int i, error = 1;
36         __u16 status;
37         struct port_info_st pi_var;
38         __u8 port_state;
39
40         for (i = 0; i < max_time; i += relax_time) {
41                 rc = get_port_info(port, &pi_var, &status);
42                 if (rc) {
43                         eprintf("");
44                         return rc;
45                 } else {
46                         if (status == 0) {
47                                 port_state = (pi_var.combined4 >> 24) & 0xf;
48                                 //port_state= pi_var.port_state;
49                                 if (port_state == 4) {
50                                         error = 0;
51                                         break;
52                                 }
53                         }
54                 }
55                 printf("+");
56                 mdelay(relax_time);
57         }
58
59         if (i >= max_time)
60                 return -1;
61
62         return 0;
63 }
64
65 static int ib_driver_init(struct pci_device *pci, udqp_t * ipoib_qph_p)
66 {
67         int rc;
68         __u8 port;
69         __u16 status;
70         __u32 qkey;
71         __u16 mlid;
72         ud_av_t av;
73         struct ib_eqe_st ib_eqe;
74         __u8 num_eqe;
75
76         tprintf("");
77         rc = ib_device_init(pci);
78         if (rc)
79                 return rc;
80
81         tprintf("");
82
83         memcpy(ib_data.bcast_gid.raw, ipv4_bcast_gid, sizeof(ipv4_bcast_gid));
84
85         port = PXE_IB_PORT;
86         rc = setup_hca(port, &ib_data.eq);
87         if (rc)
88                 return rc;
89         tprintf("setup_hca() success");
90
91         ib_data.port = port;
92
93         if(print_info)
94                 printf("boot port = %d\n", ib_data.port);
95
96         rc = wait_logic_link_up(port);
97         if (rc)
98                 return rc;
99
100         tprintf("wait_logic_link_up() success");
101
102         rc = get_guid_info(&status);
103         if (rc) {
104                 eprintf("");
105                 return rc;
106         } else if (status) {
107                 eprintf("");
108                 return rc;
109         }
110
111         tprintf("get_guid_info() success");
112
113         /* this to flush stdout that contains previous chars */
114         printf("    \n");
115         if(print_info) {
116                 __u8 *gid=ib_data.port_gid.raw;
117
118                 printf("\n");
119                 printf("port GID=%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:"
120                        "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n",
121                        gid[0],gid[1],gid[2],gid[3],gid[4],gid[5],gid[6],gid[7],
122                        gid[8],gid[9],gid[10],gid[11],gid[12],gid[13],gid[14],gid[15]);
123         }
124
125         rc = get_pkey_tbl(NULL, &status);
126         if (rc) {
127                 eprintf("");
128                 return rc;
129         } else if (status) {
130                 eprintf("");
131                 return rc;
132         }
133         rc = create_mads_qp(&ib_data.mads_qp,
134                             &ib_data.mads_snd_cq, &ib_data.mads_rcv_cq);
135         if (rc) {
136                 eprintf("");
137                 return rc;
138         }
139
140         tprintf("attempt to join mcast group ...");
141         rc = join_mc_group(&qkey, &mlid, 1);
142         if (rc) {
143                 eprintf("");
144                 return rc;
145         } else {
146                 tprintf("join_mc_group() successfull qkey=0x%lx, mlid=0x%x",
147                         qkey, mlid);
148         }
149
150         rc = create_ipoib_qp(&ib_data.ipoib_qp,
151                              &ib_data.ipoib_snd_cq,
152                              &ib_data.ipoib_rcv_cq, qkey);
153         if (rc) {
154                 eprintf("");
155                 return rc;
156         }
157
158         tprintf("create_ipoib_qp() success");
159         *ipoib_qph_p = ib_data.ipoib_qp;
160
161         tprintf("register qp to receive mcast...");
162         rc = add_qp_to_mcast_group(ib_data.bcast_gid, 1);
163         if (rc) {
164                 eprintf("");
165                 return rc;
166         } else {
167                 tprintf("add_qp_to_mcast_group() success");
168         }
169
170         /* create a broadcast group ud AV */
171         av = alloc_ud_av();
172         if (!av) {
173                 eprintf("");
174                 return -1;
175         }
176         tprintf("alloc_ud_av() success");
177         modify_av_params(av, mlid, 1, 0, 0, &ib_data.bcast_gid, BCAST_QPN);
178         tprintf("modify_av_params() success");
179         ib_data.bcast_av = av;
180
181         do {
182                 rc = poll_eq(&ib_eqe, &num_eqe);
183                 if (rc) {
184                         eprintf("");
185                         return -1;
186                 }
187                 if (num_eqe) {
188                         tprintf("num_eqe=%d", num_eqe);
189                 }
190                 tprintf("num_eqe=%d", num_eqe);
191         } while (num_eqe);
192         tprintf("eq is drained");
193
194         clear_interrupt();
195
196         return rc;
197 }
198
199 static int ib_driver_close(int fw_fatal)
200 {
201         int rc, ret = 0;
202         __u32 qkey;
203         __u16 mlid;
204
205         rc = ib_device_close();
206         if (rc) {
207                 eprintf("ib_device_close() failed");
208                 ret = 1;
209         }
210
211         tprintf("");
212         if (!fw_fatal) {
213                 rc = join_mc_group(&qkey, &mlid, 0);
214                 if (rc) {
215                         eprintf("");
216                         ret = 1;
217                 }
218                 tprintf("join_mc_group(leave) success");
219
220                 rc = add_qp_to_mcast_group(ib_data.bcast_gid, 0);
221                 if (rc) {
222                         eprintf("");
223                         ret = 1;
224                 }
225                 tprintf("add_qp_to_mcast_group(remove) success");
226
227                 rc = cmd_close_ib(ib_data.port);
228                 if (rc) {
229                         eprintf("");
230                         ret = 1;
231                 }
232                 tprintf("cmd_close_ib(%d) success", ib_data.port);
233
234                 if (destroy_udqp(ib_data.mads_qp)) {
235                         eprintf("");
236                         ret = 1;
237                 }
238
239                 if (destroy_udqp(ib_data.ipoib_qp)) {
240                         eprintf("");
241                         ret = 1;
242                 }
243         }
244
245         rc = cmd_close_hca(fw_fatal);
246         if (rc) {
247                 eprintf("");
248                 ret = 1;
249         }
250
251         if (!fw_fatal) {
252                 rc = cmd_sys_dis();
253                 if (rc) {
254                         eprintf("");
255                         ret = 1;
256                 }
257         }
258
259         return ret;
260 }
261
262 static int poll_cqe_tout(cq_t cqh, __u16 tout, void **wqe, int *good_p)
263 {
264         int rc;
265         struct ib_cqe_st ib_cqe;
266         __u8 num_cqes;
267         unsigned long end;
268
269         end = currticks() + tout;
270         do {
271                 rc = ib_poll_cq(cqh, &ib_cqe, &num_cqes);
272                 if (rc)
273                         return rc;
274
275                 if (num_cqes == 1) {
276                         if (good_p) {
277                                 *good_p = ib_cqe.is_error ? 0 : 1;
278                         }
279                         if (wqe)
280                                 *wqe = ib_cqe.wqe;
281                         return 0;
282                 }
283         }
284         while (currticks() < end);
285
286         return -1;
287 }
288
289 static u8 *get_port_gid(void)
290 {
291         return ib_data.port_gid.raw;
292 }
293
294 static __u32 ib_get_qpn(udqp_t qph)
295 {
296         __u32 qpn;
297
298         qpn = dev_get_qpn(qph);
299
300         return qpn;
301 }
302
303 static int drain_eq(void)
304 {
305         __u8 num_eqe = 0, tot_eqe = 0;
306         int rc;
307
308         do {
309                 tot_eqe += num_eqe;
310                 rc = poll_eq(ib_data.eq, &num_eqe);
311                 if (rc) {
312                         eprintf("");
313                         return -1;
314                 }
315
316                 tprintf("num_eqe=%d", num_eqe);
317         } while (num_eqe);
318         tprintf("eq is drained");
319         if (tot_eqe) {
320                 tprintf("got %d eqes", tot_eqe);
321                 return -1;
322         }
323
324         return 0;
325 }
326
327
328 static int poll_error_buf(void)
329 {
330         __u32 *ptr= dev_ib_data.error_buf_addr;
331         __u32 i;
332
333         for (i=0; i<dev_ib_data.error_buf_size; ++i, ptr++) {
334                 if ( readl(ptr) ) {
335                         return -1;
336                 }
337         }
338
339         return 0;
340 }
341
342