winverbs/lib: cache pkey table
[mirror/winof/.git] / ulp / libibumad / src / umad.cpp
1 /*\r
2  * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.\r
3  * Copyright (c) 2008 Intel Corp., Inc.  All rights reserved.\r
4  *\r
5  * This software is available to you under a choice of one of two\r
6  * licenses.  You may choose to be licensed under the terms of the GNU\r
7  * General Public License (GPL) Version 2, available from the file\r
8  * COPYING in the main directory of this source tree, or the\r
9  * OpenIB.org BSD license below:\r
10  *\r
11  *     Redistribution and use in source and binary forms, with or\r
12  *     without modification, are permitted provided that the following\r
13  *     conditions are met:\r
14  *\r
15  *      - Redistributions of source code must retain the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer.\r
18  *\r
19  *      - Redistributions in binary form must reproduce the above\r
20  *        copyright notice, this list of conditions and the following\r
21  *        disclaimer in the documentation and/or other materials\r
22  *        provided with the distribution.\r
23  *\r
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
31  * SOFTWARE.\r
32  *\r
33  */\r
34 \r
35 #include <windows.h>\r
36 #include <stdio.h>\r
37 \r
38 #include <infiniband/umad.h>\r
39 #include <infiniband/verbs.h>\r
40 #include <rdma/wvstatus.h>\r
41 #include "ibumad.h"\r
42 \r
43 #define IB_OPENIB_OUI                 (0x001405)\r
44 \r
45 #define UMAD_MAX_PKEYS  16\r
46 \r
47 typedef struct um_port\r
48 {\r
49         IWMProvider *prov;\r
50         NET64           dev_guid;\r
51         OVERLAPPED      overlap;\r
52         BOOL            pending;\r
53         UINT8           port_num;\r
54 \r
55 }       um_port_t;\r
56 \r
57 CRITICAL_SECTION crit_sec;\r
58 um_port_t ports[UMAD_MAX_PORTS];\r
59 \r
60 \r
61 __declspec(dllexport)\r
62 int umad_init(void)\r
63 {\r
64         InitializeCriticalSection(&crit_sec);\r
65         return 0;\r
66 }\r
67 \r
68 __declspec(dllexport)\r
69 int umad_done(void)\r
70 {\r
71         DeleteCriticalSection(&crit_sec);\r
72         return 0;\r
73 }\r
74 \r
75 __declspec(dllexport)\r
76 int umad_get_cas_names(char cas[][UMAD_CA_NAME_LEN], int max)\r
77 {\r
78         struct ibv_device       **list;\r
79         int                                     cnt, i;\r
80 \r
81         list = ibv_get_device_list(&cnt);\r
82         if (list == NULL) {\r
83                 return 0;\r
84         }\r
85 \r
86         for (i = 0; i < min(cnt, max); i++) {\r
87                 strcpy(cas[i], ibv_get_device_name(list[i]));\r
88         }\r
89 \r
90         ibv_free_device_list(list);\r
91         return i;\r
92 }\r
93 \r
94 __declspec(dllexport)\r
95 int umad_get_ca_portguids(char *ca_name, uint64_t *portguids, int max)\r
96 {\r
97         umad_ca_t       ca;\r
98         int                     ports = 0, i;\r
99 \r
100         if (umad_get_ca(ca_name, &ca) < 0)\r
101                 return -1;\r
102 \r
103         if (ca.numports + 1 > max) {\r
104                 umad_release_ca(&ca);\r
105                 return -ENOMEM;\r
106         }\r
107 \r
108         portguids[ports++] = 0;\r
109         for (i = 1; i <= ca.numports; i++)\r
110                 portguids[ports++] = ca.ports[i]->port_guid;\r
111 \r
112         umad_release_ca(&ca);\r
113         return ports;\r
114 }\r
115 \r
116 static void umad_convert_ca_attr(umad_ca_t *ca, ibv_device_attr *attr)\r
117 {\r
118         ca->node_type = 1;      // HCA\r
119         ca->numports = attr->phys_port_cnt;\r
120         strncpy(ca->fw_ver, attr->fw_ver, 20);\r
121         memset(ca->ca_type, 0, 40);             // TODO: determine what this should be\r
122         sprintf(ca->hw_ver, "0x%x", attr->hw_ver);\r
123         ca->node_guid = attr->node_guid;\r
124         ca->system_guid = attr->sys_image_guid;\r
125 }\r
126 \r
127 static int umad_query_port(struct ibv_context *context, umad_port_t *port)\r
128 {\r
129         ibv_port_attr   attr;\r
130         ibv_gid                 gid;\r
131         int                             i, ret;\r
132 \r
133         ret = ibv_query_port(context, (uint8_t) port->portnum, &attr);\r
134         if (ret != 0) {\r
135                 return ret;\r
136         }\r
137 \r
138         port->base_lid = attr.lid;\r
139         port->lmc = attr.lmc;\r
140         port->sm_lid = attr.sm_lid;\r
141         port->sm_sl = attr.sm_sl;\r
142         port->state = attr.state;\r
143         port->phys_state = attr.phys_state;\r
144         port->rate = attr.active_speed;\r
145         port->capmask = attr.port_cap_flags;\r
146 \r
147         // Assume GID 0 contains port GUID and gid prefix\r
148         ret = ibv_query_gid(context, (uint8_t) port->portnum, 0, &gid);\r
149         if (ret != 0) {\r
150                 return ret;\r
151         }\r
152 \r
153         port->gid_prefix = gid.global.subnet_prefix;\r
154         port->port_guid = gid.global.interface_id;\r
155 \r
156         port->pkeys_size = min(UMAD_MAX_PKEYS, attr.pkey_tbl_len);\r
157         for (i = 0; i < (int) port->pkeys_size; i++) {\r
158                 ret = ibv_query_pkey(context,(uint8_t)  port->portnum, i, &port->pkeys[i]);\r
159                 if (ret != 0) {\r
160                         return ret;\r
161                 }\r
162         }\r
163 \r
164         return 0;\r
165 }\r
166 \r
167 __declspec(dllexport)\r
168 int umad_get_ca(char *ca_name, umad_ca_t *ca)\r
169 {\r
170         struct ibv_device       **list;\r
171         struct ibv_context      *context;\r
172         ibv_device_attr         dev_attr;\r
173         int                                     cnt, i, ret = 0;\r
174         uint8_t                         *ports;\r
175         size_t                          port_size;\r
176 \r
177         list = ibv_get_device_list(&cnt);\r
178         if (list == NULL) {\r
179                 return -ENOMEM;\r
180         }\r
181 \r
182         for (i = 0; i < cnt; i++) {\r
183                 if (!strcmp(ca_name, ibv_get_device_name(list[i]))) {\r
184                         break;\r
185                 }\r
186         }\r
187 \r
188         if (i == cnt) {\r
189                 ret = -EINVAL;\r
190                 goto free;\r
191         }\r
192 \r
193         context = ibv_open_device(list[i]);\r
194         if (context == NULL) {\r
195                 ret = -ENOMEM;\r
196                 goto free;\r
197         }\r
198 \r
199         ret = ibv_query_device(context, &dev_attr);\r
200         if (ret != 0) {\r
201                 goto close;\r
202         }\r
203 \r
204         port_size = sizeof(umad_port_t) + sizeof(uint16_t) * UMAD_MAX_PKEYS;\r
205         ports = new uint8_t[port_size * dev_attr.phys_port_cnt];\r
206         if (ports == NULL) {\r
207                 ret = -ENOMEM;\r
208                 goto close;\r
209         }\r
210 \r
211         strcpy(ca->ca_name, ca_name);\r
212         umad_convert_ca_attr(ca, &dev_attr);\r
213         memset(ca->ports, 0, sizeof(ca->ports));\r
214 \r
215         for (i = 1; i <= dev_attr.phys_port_cnt; i++, ports += port_size) {\r
216 \r
217                 ca->ports[i] = (umad_port_t *) ports;\r
218                 strcpy(ca->ports[i]->ca_name, ca_name);\r
219                 ca->ports[i]->portnum = i;\r
220                 ca->ports[i]->pkeys = (uint16_t *) (ports + sizeof(umad_port_t));\r
221 \r
222                 ret = umad_query_port(context, ca->ports[i]);\r
223                 if (ret != 0) {\r
224                         delete ports;\r
225                         goto close;\r
226                 }\r
227         }\r
228 \r
229 close:\r
230         ibv_close_device(context);\r
231 free:\r
232         ibv_free_device_list(list);\r
233         return ret;\r
234 }\r
235 \r
236 __declspec(dllexport)\r
237 int umad_release_ca(umad_ca_t *ca)\r
238 {\r
239         delete ca->ports[0];\r
240         return 0;\r
241 }\r
242 \r
243 static uint64_t umad_get_ca_guid(char *ca_name)\r
244 {\r
245         umad_ca_t       ca;\r
246         uint64_t        guid;\r
247         int                     ret;\r
248 \r
249         ret = umad_get_ca(ca_name, &ca);\r
250         if (ret != 0) {\r
251                 return 0;\r
252         }\r
253 \r
254         guid = ca.node_guid;\r
255         umad_release_ca(&ca);\r
256         return guid;\r
257 }\r
258 \r
259 __declspec(dllexport)\r
260 int umad_get_port(char *ca_name, int portnum, umad_port_t *port)\r
261 {\r
262         umad_ca_t       ca;\r
263         int                     ret;\r
264 \r
265         ret = umad_get_ca(ca_name, &ca);\r
266         if (ret != 0) {\r
267                 return ret;\r
268         }\r
269 \r
270         memcpy(port, ca.ports[portnum], sizeof(umad_port_t));\r
271 \r
272         port->pkeys = new uint16_t[ca.ports[portnum]->pkeys_size];\r
273         if (port->pkeys == NULL) {\r
274                 ret = -ENOMEM;\r
275                 goto out;\r
276         }\r
277 \r
278         memcpy(port->pkeys, ca.ports[portnum]->pkeys,\r
279                    sizeof(uint16_t) * ca.ports[portnum]->pkeys_size);\r
280 out:\r
281         umad_release_ca(&ca);\r
282         return ret;\r
283 }\r
284 \r
285 __declspec(dllexport)\r
286 int umad_release_port(umad_port_t *port)\r
287 {\r
288         delete port->pkeys;\r
289         return 0;\r
290 }\r
291 \r
292 __declspec(dllexport)\r
293 int umad_get_issm_path(char *ca_name, int portnum, char path[], int max)\r
294 {\r
295         return -EINVAL;\r
296 }\r
297 \r
298 static uint8_t umad_find_port(char *ca_name, enum ibv_port_state state)\r
299 {\r
300         umad_ca_t       ca;\r
301         int                     i, ret;\r
302 \r
303         ret = umad_get_ca(ca_name, &ca);\r
304         if (ret != 0) {\r
305                 return 0;\r
306         }\r
307 \r
308         for (i = 1; i <= ca.numports; i++) {\r
309                 if (ca.ports[i]->state == state) {\r
310                         i = ca.ports[i]->portnum;\r
311                         umad_release_ca(&ca);\r
312                         return (uint8_t) i;\r
313                 }\r
314         }\r
315 \r
316         umad_release_ca(&ca);\r
317         return 0;\r
318 }\r
319 \r
320 static int umad_find_ca_port(enum ibv_port_state state, char *ca_name, uint8_t *port)\r
321 {\r
322         char            names[8][UMAD_CA_NAME_LEN];\r
323         int                     cnt, i;\r
324 \r
325         cnt = umad_get_cas_names(names, 8);\r
326 \r
327         for (i = 0; i < cnt; i++) {\r
328                 *port = umad_find_port(names[i], state);\r
329                 if (*port != 0) {\r
330                         strcpy(ca_name, names[i]);\r
331                         return 0;\r
332                 }\r
333         }\r
334         return -1;\r
335 }\r
336 \r
337 static int umad_resolve_ca_port(char *ca_name, uint8_t *port)\r
338 {\r
339         int ret;\r
340 \r
341         if (ca_name[0] != NULL) {\r
342                 if (*port != 0) {\r
343                         return 0;\r
344                 }\r
345 \r
346                 *port = umad_find_port(ca_name, IBV_PORT_ACTIVE);\r
347                 if (*port != 0) {\r
348                         return 0;\r
349                 }\r
350                 *port = umad_find_port(ca_name, IBV_PORT_INIT);\r
351                 if (*port != 0) {\r
352                         return 0;\r
353                 }\r
354                 *port = umad_find_port(ca_name, IBV_PORT_DOWN);\r
355                 return (*port == 0);\r
356         }\r
357 \r
358         ret = umad_find_ca_port(IBV_PORT_ACTIVE, ca_name, port);\r
359         if (ret == 0) {\r
360                 return 0;\r
361         }\r
362         ret = umad_find_ca_port(IBV_PORT_INIT, ca_name, port);\r
363         if (ret == 0) {\r
364                 return 0;\r
365         }\r
366         ret = umad_find_ca_port(IBV_PORT_DOWN, ca_name, port);\r
367         return ret;\r
368 }\r
369 \r
370 __declspec(dllexport)\r
371 int umad_open_port(char *ca_name, int portnum)\r
372 {\r
373         char    name[UMAD_CA_NAME_LEN];\r
374         uint8_t port;\r
375         HRESULT hr;\r
376         int             portid;\r
377 \r
378         if (ca_name != NULL) {\r
379                 strcpy(name, ca_name);\r
380                 port = (uint8_t) portnum;\r
381         } else {\r
382                 name[0] = NULL;\r
383                 port = 0;\r
384         }\r
385 \r
386         hr = umad_resolve_ca_port(name, &port);\r
387         if (FAILED(hr)) {\r
388                 return hr;\r
389         }\r
390 \r
391         EnterCriticalSection(&crit_sec);\r
392         for (portid = 0; portid < UMAD_MAX_PORTS; portid++) {\r
393                 if (ports[portid].prov == NULL) {\r
394                         break;\r
395                 }\r
396         }\r
397 \r
398         if (portid == UMAD_MAX_PORTS) {\r
399                 portid = -ENOMEM;\r
400                 goto out;\r
401         }\r
402 \r
403         ports[portid].overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\r
404         if (ports[portid].overlap.hEvent == NULL) {\r
405                 portid = -ENOMEM;\r
406                 goto out;\r
407         }\r
408 \r
409         hr = WmGetObject(IID_IWMProvider, (LPVOID*) &ports[portid].prov);\r
410         if (FAILED(hr)) {\r
411                 CloseHandle(ports[portid].overlap.hEvent);\r
412                 portid = GetLastError() & 0x80000000;\r
413                 goto out;\r
414         }\r
415 \r
416         ports[portid].dev_guid = umad_get_ca_guid(name);\r
417         ports[portid].port_num = port;\r
418 \r
419 out:\r
420         LeaveCriticalSection(&crit_sec);\r
421         return portid;\r
422 }\r
423 \r
424 __declspec(dllexport)\r
425 int umad_close_port(int portid)\r
426 {\r
427         CloseHandle(ports[portid].overlap.hEvent);\r
428         ports[portid].prov->Release();\r
429 \r
430         EnterCriticalSection(&crit_sec);\r
431         ports[portid].prov = NULL;\r
432         LeaveCriticalSection(&crit_sec);\r
433 \r
434         return 0;\r
435 }\r
436 \r
437 __declspec(dllexport)\r
438 int umad_set_grh_net(void *umad, void *mad_addr)\r
439 {\r
440         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
441         struct ib_mad_addr *addr = (struct ib_mad_addr *) mad_addr;\r
442 \r
443         if (mad_addr) {\r
444                 mad->addr.grh_present = 1;\r
445                 memcpy(mad->addr.gid, addr->gid, 16);\r
446                 mad->addr.flow_label = addr->flow_label;\r
447                 mad->addr.hop_limit = addr->hop_limit;\r
448                 mad->addr.traffic_class = addr->traffic_class;\r
449         } else\r
450                 mad->addr.grh_present = 0;\r
451         return 0;\r
452 }\r
453 \r
454 __declspec(dllexport)\r
455 int umad_set_grh(void *umad, void *mad_addr)\r
456 {\r
457         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
458         struct ib_mad_addr *addr = (struct ib_mad_addr *) mad_addr;\r
459 \r
460         if (mad_addr) {\r
461                 mad->addr.grh_present = 1;\r
462                 memcpy(mad->addr.gid, addr->gid, 16);\r
463                 mad->addr.flow_label = htonl(addr->flow_label);\r
464                 mad->addr.hop_limit = addr->hop_limit;\r
465                 mad->addr.traffic_class = addr->traffic_class;\r
466         } else\r
467                 mad->addr.grh_present = 0;\r
468         return 0;\r
469 }\r
470 \r
471 __declspec(dllexport)\r
472 int umad_set_pkey(void *umad, int pkey_index)\r
473 {\r
474         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
475 \r
476         mad->addr.pkey_index = (uint16_t) pkey_index;\r
477         return 0;\r
478 }\r
479 \r
480 __declspec(dllexport)\r
481 int umad_get_pkey(void *umad)\r
482 {\r
483         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
484 \r
485         return mad->addr.pkey_index;\r
486 }\r
487 \r
488 __declspec(dllexport)\r
489 int umad_set_addr(void *umad, int dlid, int dqp, int sl, int qkey)\r
490 {\r
491         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
492 \r
493         mad->addr.qpn = htonl(dqp);\r
494         mad->addr.lid = htons((uint16_t) dlid);\r
495         mad->addr.qkey = htonl(qkey);\r
496         mad->addr.sl = (uint8_t) sl;\r
497         return 0;\r
498 }\r
499 \r
500 __declspec(dllexport)\r
501 int umad_set_addr_net(void *umad, int dlid, int dqp, int sl, int qkey)\r
502 {\r
503         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
504 \r
505         mad->addr.qpn = dqp;\r
506         mad->addr.lid = (uint16_t) dlid;\r
507         mad->addr.qkey = qkey;\r
508         mad->addr.sl = (uint8_t) sl;\r
509 \r
510         return 0;\r
511 }\r
512 \r
513 __declspec(dllexport)\r
514 int umad_status(void *umad)\r
515 {\r
516         return ((struct ib_user_mad *) umad)->status;\r
517 }\r
518 \r
519 __declspec(dllexport)\r
520 ib_mad_addr_t *umad_get_mad_addr(void *umad)\r
521 {\r
522         return &((struct ib_user_mad *) umad)->addr;\r
523 }\r
524 \r
525 __declspec(dllexport)\r
526 void *umad_get_mad(void *umad)\r
527 {\r
528         return ((struct ib_user_mad *)umad)->data;\r
529 }\r
530 \r
531 __declspec(dllexport)\r
532 void *umad_alloc(int num, size_t size)\r
533 {\r
534         return new uint8_t[num * size];\r
535 }\r
536 \r
537 __declspec(dllexport)\r
538 void umad_free(void *umad)\r
539 {\r
540         delete umad;\r
541 }\r
542 \r
543 __declspec(dllexport)\r
544 size_t umad_size(void)\r
545 {\r
546         return sizeof(struct ib_user_mad);\r
547 }\r
548 \r
549 __declspec(dllexport)\r
550 int umad_send(int portid, int agentid, void *umad, int length,\r
551                           int timeout_ms, int retries)\r
552 {\r
553         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
554         HRESULT hr;\r
555 \r
556         mad->agent_id = agentid;\r
557         mad->reserved_id = 0;\r
558 \r
559         mad->timeout_ms = (uint32_t) timeout_ms;\r
560         mad->retries    = (uint32_t) retries;\r
561         mad->length             = (uint32_t) length;\r
562 \r
563         hr = ports[portid].prov->Send((WM_MAD *) mad, NULL);\r
564         if (FAILED(hr)) {\r
565                 return GetLastError();\r
566         }\r
567 \r
568         return 0;\r
569 }\r
570 \r
571 __declspec(dllexport)\r
572 int umad_recv(int portid, void *umad, int *length, int timeout_ms)\r
573 {\r
574         WM_MAD          *mad = (WM_MAD *) umad;\r
575         um_port_t       *port;\r
576         HRESULT         hr;\r
577 \r
578         port = &ports[portid];\r
579         hr = port->prov->Receive(mad, sizeof(WM_MAD) + (size_t) *length, &port->overlap);\r
580 \r
581         if (hr == WV_IO_PENDING) {\r
582                 if (port->pending && timeout_ms == 0) {\r
583                         do {\r
584                                 hr = WaitForSingleObject(port->overlap.hEvent, 250);\r
585                         } while (hr == WAIT_TIMEOUT && port->pending);\r
586                 } else {\r
587                         hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);\r
588                         if (hr == WAIT_TIMEOUT) {\r
589                                 return -EWOULDBLOCK;\r
590                         }\r
591                 }\r
592         }\r
593 \r
594         if (FAILED(hr)) {\r
595                 return -EIO;\r
596         }\r
597 \r
598         if (mad->Length <= (UINT32) *length) {\r
599                 port->pending = FALSE;\r
600                 hr = (HRESULT) mad->Id;\r
601         } else {\r
602                 errno = ENOSPC;\r
603                 hr = -ENOSPC;\r
604         }\r
605 \r
606         *length = mad->Length;\r
607         return hr;\r
608 }\r
609 \r
610 __declspec(dllexport)\r
611 int umad_poll(int portid, int timeout_ms)\r
612 {\r
613         WM_MAD          mad;\r
614         um_port_t       *port;\r
615         HRESULT         hr;\r
616 \r
617         port = &ports[portid];\r
618         hr = port->prov->Receive(&mad, sizeof mad, &port->overlap);\r
619 \r
620         if (hr == WV_IO_PENDING) {\r
621                 hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);\r
622                 if (hr == WAIT_TIMEOUT) {\r
623                         return -ETIMEDOUT;\r
624                 }\r
625         }\r
626 \r
627         if (FAILED(hr) && hr != ERROR_MORE_DATA) {\r
628                 return -EIO;\r
629         }\r
630 \r
631         port->pending = TRUE;\r
632         return 0;\r
633 }\r
634 \r
635 __declspec(dllexport)\r
636 int umad_register_oui(int portid, int mgmt_class, uint8_t rmpp_version,\r
637                                           uint8_t oui[3], long method_mask[16/sizeof(long)])\r
638 {\r
639         WM_REGISTER reg;\r
640         UINT64          id = 0;\r
641 \r
642         UNREFERENCED_PARAMETER(rmpp_version);\r
643 \r
644         reg.Guid = ports[portid].dev_guid;\r
645         reg.Qpn = (mgmt_class == 0x01 || mgmt_class == 0x81) ? 0 : htonl(1);\r
646         reg.Port = ports[portid].port_num;\r
647         reg.Class = (uint8_t) mgmt_class;\r
648         reg.Version = 1;\r
649         memset(reg.Reserved, 0, sizeof(reg.Reserved));\r
650         memcpy(reg.Oui, oui, sizeof(oui));\r
651         if (method_mask != NULL) {\r
652                 memcpy(reg.Methods, method_mask, sizeof(reg.Methods));\r
653         } else {\r
654                 memset(reg.Methods, 0, sizeof(reg.Methods));\r
655         }\r
656         ports[portid].prov->Register(&reg, &id);\r
657 \r
658         return (int) id;\r
659 }\r
660 \r
661 __declspec(dllexport)\r
662 int umad_register(int portid, int mgmt_class, int mgmt_version,\r
663                                   uint8_t rmpp_version, long method_mask[16/sizeof(long)])\r
664 {\r
665         uint8_t oui[3];\r
666 \r
667         memset(oui, 0, 3);\r
668         return umad_register_oui(portid, mgmt_class, rmpp_version, oui, method_mask);\r
669 }\r
670 \r
671 __declspec(dllexport)\r
672 int umad_unregister(int portid, int agentid)\r
673 {\r
674         ports[portid].pending = FALSE;\r
675         return ports[portid].prov->Deregister((UINT64) agentid);\r
676 }\r
677 \r
678 HANDLE umad_get_fd(int portid)\r
679 {\r
680         return ports[portid].prov->GetFileHandle();\r
681 }\r
682 \r
683 __declspec(dllexport)\r
684 int umad_debug(int level)\r
685 {\r
686         UNREFERENCED_PARAMETER(level);\r
687         return 0;\r
688 }\r
689 \r
690 __declspec(dllexport)\r
691 void umad_addr_dump(ib_mad_addr_t *addr)\r
692 {\r
693         printf("umad_addr:\n");\r
694         printf("\tqpn           0x%x\n", addr->qpn);\r
695         printf("\tqkey          0x%x\n", addr->qkey);\r
696         printf("\tsl            0x%x\n", addr->sl);\r
697         printf("\tlid           0x%x\n", addr->lid);\r
698         printf("\tpkey_index    0x%x\n", addr->pkey_index);\r
699         printf("\tpath_bits     0x%x\n", addr->path_bits);\r
700         printf("\trate          0x%x\n", addr->reserved_rate);\r
701 \r
702         printf("\tgrh_present   0x%x\n", addr->grh_present);\r
703         if (addr->grh_present) {\r
704                 printf("\tgid_index     0x%x\n", addr->gid_index);\r
705                 printf("\tgid           0x%x %x\n",\r
706                         (uint64_t) addr->gid, (uint64_t) (addr->gid + 8));\r
707                 printf("\tflow_lable    0x%x\n", addr->flow_label);\r
708                 printf("\thop_limit     0x%x\n", addr->hop_limit);\r
709                 printf("\ttraffic_class 0x%x\n", addr->qpn);\r
710         }\r
711 }\r
712 \r
713 __declspec(dllexport)\r
714 void umad_dump(void *umad)\r
715 {\r
716         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
717         int i;\r
718 \r
719         umad_addr_dump(&mad->addr);\r
720         printf("umad_data\n");\r
721         printf("offset: hex data\n");\r
722         for (i = 0; i < 256; i += 4) {\r
723                 printf("%03d: ", i);\r
724                 printf("%02x %02x %02x %02x\n", mad->data[i], mad->data[i + 1],\r
725                         mad->data[i + 2], mad->data[i + 3]);\r
726         }\r
727 }\r