590fb94dbb633b3780703e24000bfa0cf8580129
[people/pcmattman/gpxe.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 unsigned long ipoib_qkey;
66
67 static int ib_driver_init(struct pci_device *pci, udqp_t * ipoib_qph_p)
68 {
69         int rc;
70         __u8 port;
71         __u16 status;
72         __u32 qkey;
73         __u16 mlid;
74         ud_av_t av;
75         struct ib_eqe_st ib_eqe;
76         __u8 num_eqe;
77
78         tprintf("");
79         rc = ib_device_init(pci);
80         if (rc)
81                 return rc;
82
83         tprintf("");
84
85         memcpy(ib_data.bcast_gid.raw, ipv4_bcast_gid, sizeof(ipv4_bcast_gid));
86
87         port = PXE_IB_PORT;
88         rc = setup_hca(port, &ib_data.eq);
89         if (rc)
90                 return rc;
91         tprintf("setup_hca() success");
92
93         ib_data.port = port;
94
95         if(print_info)
96                 printf("boot port = %d\n", ib_data.port);
97
98         rc = wait_logic_link_up(port);
99         if (rc)
100                 return rc;
101
102         tprintf("wait_logic_link_up() success");
103
104         rc = get_guid_info(&status);
105         if (rc) {
106                 eprintf("");
107                 return rc;
108         } else if (status) {
109                 eprintf("");
110                 return rc;
111         }
112
113         tprintf("get_guid_info() success");
114
115         /* this to flush stdout that contains previous chars */
116         printf("    \n");
117         if(print_info) {
118                 __u8 *gid=ib_data.port_gid.raw;
119
120                 printf("\n");
121                 printf("port GID=%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:"
122                        "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n",
123                        gid[0],gid[1],gid[2],gid[3],gid[4],gid[5],gid[6],gid[7],
124                        gid[8],gid[9],gid[10],gid[11],gid[12],gid[13],gid[14],gid[15]);
125         }
126
127         rc = get_pkey_tbl(NULL, &status);
128         if (rc) {
129                 eprintf("");
130                 return rc;
131         } else if (status) {
132                 eprintf("");
133                 return rc;
134         }
135         rc = create_mads_qp(&ib_data.mads_qp,
136                             &ib_data.mads_snd_cq, &ib_data.mads_rcv_cq);
137         if (rc) {
138                 eprintf("");
139                 return rc;
140         }
141
142         tprintf("attempt to join mcast group ...");
143         rc = join_mc_group(&qkey, &mlid, 1);
144         if (rc) {
145                 eprintf("");
146                 return rc;
147         } else {
148                 tprintf("join_mc_group() successfull qkey=0x%lx, mlid=0x%x",
149                         qkey, mlid);
150         }
151
152         ipoib_qkey = qkey;
153
154 #if 0
155         rc = create_ipoib_qp(&ib_data.ipoib_qp,
156                              &ib_data.ipoib_snd_cq,
157                              &ib_data.ipoib_rcv_cq, qkey);
158         if (rc) {
159                 eprintf("");
160                 return rc;
161         }
162
163         tprintf("create_ipoib_qp() success");
164         *ipoib_qph_p = ib_data.ipoib_qp;
165
166         tprintf("register qp to receive mcast...");
167         rc = add_qp_to_mcast_group(ib_data.bcast_gid, 1);
168         if (rc) {
169                 eprintf("");
170                 return rc;
171         } else {
172                 tprintf("add_qp_to_mcast_group() success");
173         }
174 #endif
175
176         /* create a broadcast group ud AV */
177         av = alloc_ud_av();
178         if (!av) {
179                 eprintf("");
180                 return -1;
181         }
182         tprintf("alloc_ud_av() success");
183         modify_av_params(av, mlid, 1, 0, 0, &ib_data.bcast_gid, BCAST_QPN);
184         tprintf("modify_av_params() success");
185         ib_data.bcast_av = av;
186
187 #if ! CREATE_OWN
188         rc = create_ipoib_qp(&ib_data.ipoib_qp,
189                              &ib_data.ipoib_snd_cq,
190                              &ib_data.ipoib_rcv_cq, qkey);
191         if (rc) {
192                 eprintf("");
193                 return rc;
194         }
195
196         tprintf("create_ipoib_qp() success");
197         *ipoib_qph_p = ib_data.ipoib_qp;
198 #endif
199
200         do {
201                 rc = poll_eq(&ib_eqe, &num_eqe);
202                 if (rc) {
203                         eprintf("");
204                         return -1;
205                 }
206                 if (num_eqe) {
207                         tprintf("num_eqe=%d", num_eqe);
208                 }
209                 tprintf("num_eqe=%d", num_eqe);
210         } while (num_eqe);
211         tprintf("eq is drained");
212
213         clear_interrupt();
214
215         return rc;
216 }
217
218 static int ib_driver_close(int fw_fatal)
219 {
220         int rc, ret = 0;
221         __u32 qkey;
222         __u16 mlid;
223
224         rc = ib_device_close();
225         if (rc) {
226                 eprintf("ib_device_close() failed");
227                 ret = 1;
228         }
229
230         tprintf("");
231         if (!fw_fatal) {
232                 rc = join_mc_group(&qkey, &mlid, 0);
233                 if (rc) {
234                         eprintf("");
235                         ret = 1;
236                 }
237                 tprintf("join_mc_group(leave) success");
238
239                 rc = add_qp_to_mcast_group(ib_data.bcast_gid, 0);
240                 if (rc) {
241                         eprintf("");
242                         ret = 1;
243                 }
244                 tprintf("add_qp_to_mcast_group(remove) success");
245
246                 rc = cmd_close_ib(ib_data.port);
247                 if (rc) {
248                         eprintf("");
249                         ret = 1;
250                 }
251                 tprintf("cmd_close_ib(%d) success", ib_data.port);
252
253                 if (destroy_udqp(ib_data.mads_qp)) {
254                         eprintf("");
255                         ret = 1;
256                 }
257
258                 if (destroy_udqp(ib_data.ipoib_qp)) {
259                         eprintf("");
260                         ret = 1;
261                 }
262         }
263
264         rc = cmd_close_hca(fw_fatal);
265         if (rc) {
266                 eprintf("");
267                 ret = 1;
268         }
269
270         rc = unset_hca();
271         if (rc) {
272                 eprintf("");
273                 ret = 1;
274         }
275
276         return ret;
277 }
278
279 static int poll_cqe_tout(cq_t cqh, __u16 tout, void **wqe, int *good_p)
280 {
281         int rc;
282         struct ib_cqe_st ib_cqe;
283         __u8 num_cqes;
284         unsigned long end;
285
286         end = currticks() + tout;
287         do {
288                 rc = ib_poll_cq(cqh, &ib_cqe, &num_cqes);
289                 if (rc)
290                         return rc;
291
292                 if (num_cqes == 1) {
293                         if (good_p) {
294                                 *good_p = ib_cqe.is_error ? 0 : 1;
295                         }
296                         if (wqe)
297                                 *wqe = ib_cqe.wqe;
298                         return 0;
299                 }
300         }
301         while (currticks() < end);
302
303         return -1;
304 }
305
306 static u8 *get_port_gid(void)
307 {
308         return ib_data.port_gid.raw;
309 }
310
311 static __u32 ib_get_qpn(udqp_t qph)
312 {
313         __u32 qpn;
314
315         qpn = dev_get_qpn(qph);
316
317         return qpn;
318 }
319
320 static int drain_eq(void)
321 {
322         __u8 num_eqe = 0, tot_eqe = 0;
323         int rc;
324
325         do {
326                 tot_eqe += num_eqe;
327                 rc = poll_eq(ib_data.eq, &num_eqe);
328                 if (rc) {
329                         eprintf("");
330                         return -1;
331                 }
332
333                 tprintf("num_eqe=%d", num_eqe);
334         } while (num_eqe);
335         tprintf("eq is drained");
336         if (tot_eqe) {
337                 tprintf("got %d eqes", tot_eqe);
338                 return -1;
339         }
340
341         return 0;
342 }
343
344
345 static int poll_error_buf(void)
346 {
347         __u32 *ptr= dev_ib_data.error_buf_addr;
348         __u32 i;
349
350         for (i=0; i<dev_ib_data.error_buf_size; ++i, ptr++) {
351                 if ( readl(ptr) ) {
352                         return -1;
353                 }
354         }
355
356         return 0;
357 }
358
359