54377205eca50ed8b44f1bc7c639247ab47c4e65
[mirror/winof/.git] / ulp / libibmad / src / serv.c
1 /*\r
2  * Copyright (c) 2004,2005 Voltaire Inc.  All rights reserved.\r
3  *\r
4  * This software is available to you under the OpenFabrics.org BSD license\r
5  * below:\r
6  *\r
7  *     Redistribution and use in source and binary forms, with or\r
8  *     without modification, are permitted provided that the following\r
9  *     conditions are met:\r
10  *\r
11  *      - Redistributions of source code must retain the above\r
12  *        copyright notice, this list of conditions and the following\r
13  *        disclaimer.\r
14  *\r
15  *      - Redistributions in binary form must reproduce the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer in the documentation and/or other materials\r
18  *        provided with the distribution.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV\r
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
27  * SOFTWARE.\r
28  */\r
29 \r
30 #if HAVE_CONFIG_H\r
31 #  include <config.h>\r
32 #endif /* HAVE_CONFIG_H */\r
33 \r
34 #include <stdio.h>\r
35 #include <stdlib.h>\r
36 \r
37 #if defined(_WIN32) || defined(_WIN64)\r
38 #include <windows.h>\r
39 #include <winsock2.h>\r
40 #else\r
41 #include <unistd.h>\r
42 #include <pthread.h>\r
43 #include <sys/time.h>\r
44 #include <string.h>\r
45 #include <netinet/in.h>\r
46 #endif\r
47 \r
48 #include <infiniband/umad.h>\r
49 #include <mad.h>\r
50 \r
51 #undef DEBUG\r
52 #define DEBUG   if (ibdebug)    IBWARN\r
53 \r
54 MAD_EXPORT int\r
55 mad_send(ib_rpc_t *rpc, ib_portid_t *dport, ib_rmpp_hdr_t *rmpp, void *data)\r
56 {\r
57         uint8_t pktbuf[1024];\r
58         void *umad = pktbuf;\r
59 \r
60         memset(pktbuf, 0, umad_size());\r
61 \r
62         DEBUG("rmpp %p data %p", rmpp, data);\r
63 \r
64         if (mad_build_pkt(umad, rpc, dport, rmpp, data) < 0)\r
65                 return 0;\r
66 \r
67         if (ibdebug) {\r
68                 IBWARN("data offs %d sz %d", rpc->dataoffs, rpc->datasz);\r
69                 xdump(stderr, "mad send data\n",\r
70                         (char *)umad_get_mad(umad) + rpc->dataoffs, rpc->datasz);\r
71         }\r
72 \r
73         if (umad_send(madrpc_portid(), mad_class_agent(rpc->mgtclass),\r
74                       umad, IB_MAD_SIZE, rpc->timeout, 0) < 0) {\r
75                 IBWARN("send failed; %m");\r
76                 return -1;\r
77         }\r
78 \r
79         return 0;\r
80 }\r
81 \r
82 MAD_EXPORT int\r
83 mad_respond(void *umad, ib_portid_t *portid, uint32_t rstatus)\r
84 {\r
85         uint8_t *mad = umad_get_mad(umad);\r
86         ib_mad_addr_t *mad_addr;\r
87         ib_rpc_t rpc = {0};\r
88         ib_portid_t rport;\r
89         int is_smi;\r
90 \r
91         if (!portid) {\r
92                 if (!(mad_addr = umad_get_mad_addr(umad)))\r
93                         return -1;\r
94 \r
95                 memset(&rport, 0, sizeof(rport));\r
96 \r
97                 rport.lid = ntohs(mad_addr->lid);\r
98                 rport.qp = ntohl(mad_addr->qpn);\r
99                 rport.qkey = ntohl(mad_addr->qkey);\r
100                 rport.sl = mad_addr->sl;\r
101 \r
102                 portid = &rport;\r
103         }\r
104 \r
105         DEBUG("dest %s", portid2str(portid));\r
106 \r
107         rpc.mgtclass = mad_get_field(mad, 0, IB_MAD_MGMTCLASS_F);\r
108 \r
109         rpc.method = mad_get_field(mad, 0, IB_MAD_METHOD_F);\r
110         if (rpc.method == IB_MAD_METHOD_SET)\r
111                 rpc.method = IB_MAD_METHOD_GET;\r
112         if (rpc.method != IB_MAD_METHOD_SEND)\r
113                 rpc.method |= IB_MAD_RESPONSE;\r
114 \r
115         rpc.attr.id = mad_get_field(mad, 0, IB_MAD_ATTRID_F);\r
116         rpc.attr.mod = mad_get_field(mad, 0, IB_MAD_ATTRMOD_F);\r
117         if (rpc.mgtclass == IB_SA_CLASS)\r
118                 rpc.recsz = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);\r
119         if (mad_is_vendor_range2(rpc.mgtclass))\r
120                 rpc.oui = mad_get_field(mad, 0, IB_VEND2_OUI_F);\r
121 \r
122         rpc.trid = mad_get_field64(mad, 0, IB_MAD_TRID_F);\r
123 \r
124         /* cleared by default: timeout, datasz, dataoffs, mkey, mask */\r
125 \r
126         is_smi = rpc.mgtclass == IB_SMI_CLASS ||\r
127                  rpc.mgtclass == IB_SMI_DIRECT_CLASS;\r
128 \r
129         if (is_smi)\r
130                 portid->qp = 0;\r
131         else if (!portid->qp)\r
132                  portid->qp = 1;\r
133 \r
134         if (!portid->qkey && portid->qp == 1)\r
135                 portid->qkey = IB_DEFAULT_QP1_QKEY;\r
136 \r
137         DEBUG("qp 0x%x class 0x%x method %d attr 0x%x mod 0x%x datasz %d off %d qkey %x",\r
138                 portid->qp, rpc.mgtclass, rpc.method, rpc.attr.id, rpc.attr.mod,\r
139                 rpc.datasz, rpc.dataoffs, portid->qkey);\r
140 \r
141         if (mad_build_pkt(umad, &rpc, portid, 0, 0) < 0)\r
142                 return -1;\r
143 \r
144         if (ibdebug > 1)\r
145                 xdump(stderr, "mad respond pkt\n", mad, IB_MAD_SIZE);\r
146 \r
147         if (umad_send(madrpc_portid(), mad_class_agent(rpc.mgtclass), umad,\r
148                       IB_MAD_SIZE, rpc.timeout, 0) < 0) {\r
149                 DEBUG("send failed; %m");\r
150                 return -1;\r
151         }\r
152 \r
153         return 0;\r
154 }\r
155 \r
156 MAD_EXPORT void *\r
157 mad_receive(void *umad, int timeout)\r
158 {\r
159         void *mad = umad ? umad : umad_alloc(1, umad_size() + IB_MAD_SIZE);\r
160         int agent;\r
161         int length = IB_MAD_SIZE;\r
162 \r
163         if ((agent = umad_recv(madrpc_portid(), mad,\r
164                                &length, timeout)) < 0) {\r
165                 if (!umad)\r
166                         umad_free(mad);\r
167                 DEBUG("recv failed: %m");\r
168                 return 0;\r
169         }\r
170 \r
171         return mad;\r
172 }\r
173 \r
174 MAD_EXPORT void *\r
175 mad_alloc(void)\r
176 {\r
177         return umad_alloc(1, umad_size() + IB_MAD_SIZE);\r
178 }\r
179 \r
180 MAD_EXPORT void\r
181 mad_free(void *umad)\r
182 {\r
183         umad_free(umad);\r
184 }\r