2 * Copyright (c) 2006-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38 * Implementation of SLtoVL and VL Arbitration testing flow..
39 * Top level is osmt_run_slvl_and_vlarb_records_flow:
40 * osmt_query_all_ports_vl_arb
41 * osmt_query_all_ports_slvl_map
51 #include <complib/cl_debug.h>
54 /**********************************************************************
55 **********************************************************************/
56 static ib_api_status_t
57 osmtest_write_vl_arb_table(IN osmtest_t * const p_osmt,
59 IN const ib_vl_arb_table_record_t * const p_rec)
62 cl_status_t status = IB_SUCCESS;
64 OSM_LOG_ENTER(&p_osmt->log);
67 "VL_ARBITRATION_TABLE\n"
71 cl_ntoh16(p_rec->lid),
72 p_rec->port_num, p_rec->block_num);
75 for (i = 0; i < 32; i++)
76 fprintf(fh, "| %-2u ", i);
77 fprintf(fh, "|\nVL: ");
79 for (i = 0; i < 32; i++)
80 fprintf(fh, "|0x%02X", p_rec->vl_arb_tbl.vl_entry[i].vl);
81 fprintf(fh, "|\nWEIGHT:");
83 for (i = 0; i < 32; i++)
84 fprintf(fh, "|0x%02X", p_rec->vl_arb_tbl.vl_entry[i].weight);
85 fprintf(fh, "|\nEND\n\n");
88 OSM_LOG_EXIT(&p_osmt->log);
92 /**********************************************************************
93 * GET A SINGLE PORT INFO BY NODE LID AND PORT NUMBER
94 **********************************************************************/
96 osmt_query_vl_arb(IN osmtest_t * const p_osmt,
97 IN ib_net16_t const lid,
98 IN uint8_t const port_num,
99 IN uint8_t const block_num, IN FILE * fh)
101 osmtest_req_context_t context;
102 ib_api_status_t status = IB_SUCCESS;
103 osmv_user_query_t user;
104 osmv_query_req_t req;
105 ib_vl_arb_table_record_t record, *p_rec;
107 OSM_LOG_ENTER(&p_osmt->log);
109 OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
110 "Getting VL_Arbitration Table for port with LID 0x%X Num:0x%X\n",
111 cl_ntoh16(lid), port_num);
114 * Do a blocking query for this record in the subnet.
115 * The result is returned in the result field of the caller's
118 * The query structures are locals.
120 memset(&req, 0, sizeof(req));
121 memset(&user, 0, sizeof(user));
122 memset(&context, 0, sizeof(context));
124 context.p_osmt = p_osmt;
127 record.port_num = port_num;
128 record.block_num = block_num;
129 user.p_attr = &record;
131 req.query_type = OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK;
132 req.timeout_ms = p_osmt->opt.transaction_timeout;
133 req.retry_cnt = p_osmt->opt.retry_count;
134 req.flags = OSM_SA_FLAGS_SYNC;
135 req.query_context = &context;
136 req.pfn_query_cb = osmtest_query_res_cb;
137 req.p_query_input = &user;
140 status = osmv_query_sa(p_osmt->h_bind, &req);
142 if (status != IB_SUCCESS) {
143 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0405: "
144 "ib_query failed (%s)\n", ib_get_err_str(status));
148 status = context.result.status;
150 if (status != IB_SUCCESS) {
151 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0466: "
152 "ib_query failed (%s)\n", ib_get_err_str(status));
154 if (status == IB_REMOTE_ERROR) {
155 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
156 "Remote error = %s\n",
157 ib_get_mad_status_str(osm_madw_get_mad_ptr
165 p_rec = osmv_get_query_result(context.result.p_result_madw, 0);
167 osmtest_write_vl_arb_table(p_osmt, fh, p_rec);
172 * Return the IB query MAD to the pool as necessary.
174 if (context.result.p_result_madw != NULL) {
175 osm_mad_pool_put(&p_osmt->mad_pool,
176 context.result.p_result_madw);
177 context.result.p_result_madw = NULL;
180 OSM_LOG_EXIT(&p_osmt->log);
184 static ib_api_status_t
185 osmt_query_all_ports_vl_arb(IN osmtest_t * const p_osmt, IN FILE * fh)
187 cl_status_t status = CL_SUCCESS;
190 uint8_t block, anyErr = 0;
192 OSM_LOG_ENTER(&p_osmt->log);
194 OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
195 "Obtaining ALL Ports VL Arbitration Tables\n");
198 * Go over all ports that exist in the subnet
199 * get the relevant VLarbs
202 p_tbl = &p_osmt->exp_subn.port_key_tbl;
204 p_src_port = (port_t *) cl_qmap_head(p_tbl);
206 while (p_src_port != (port_t *) cl_qmap_end(p_tbl)) {
208 /* HACK we use capability_mask to know diff a CA port from switch port */
209 if (p_src_port->rec.port_info.capability_mask) {
210 /* this is an hca port */
211 for (block = 1; block <= 4; block++) {
212 /* NOTE to comply we must set port number to 0 and the SA should figure it out */
213 /* since it is a CA port */
215 osmt_query_vl_arb(p_osmt,
216 p_src_port->rec.lid, 0,
218 if (status != IB_SUCCESS) {
219 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
221 "Failed to get Lid:0x%X Port:0x%X (%s)\n",
222 cl_ntoh16(p_src_port->rec.lid),
223 0, ib_get_err_str(status));
228 /* this is a switch port */
229 for (block = 1; block <= 4; block++) {
231 osmt_query_vl_arb(p_osmt,
233 p_src_port->rec.port_num,
235 if (status != IB_SUCCESS) {
236 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
238 "Failed to get Lid:0x%X Port:0x%X (%s)\n",
239 cl_ntoh16(p_src_port->rec.lid),
240 p_src_port->rec.port_num,
241 ib_get_err_str(status));
247 p_src_port = (port_t *) cl_qmap_next(&p_src_port->map_item);
250 OSM_LOG_EXIT(&p_osmt->log);
257 /*******************************************************************************
259 *******************************************************************************/
260 static ib_api_status_t
261 osmtest_write_slvl_map_table(IN osmtest_t * const p_osmt,
263 IN const ib_slvl_table_record_t * const p_rec)
266 cl_status_t status = IB_SUCCESS;
268 OSM_LOG_ENTER(&p_osmt->log);
274 "out_port_num 0x%X\n",
275 cl_ntoh16(p_rec->lid),
276 p_rec->in_port_num, p_rec->out_port_num);
279 for (i = 0; i < 16; i++)
280 fprintf(fh, "| %-2u ", i);
281 fprintf(fh, "|\nVL:");
283 for (i = 0; i < 16; i++)
284 fprintf(fh, "| 0x%01X ",
285 ib_slvl_table_get(&p_rec->slvl_tbl, (uint8_t) i));
286 fprintf(fh, "|\nEND\n\n");
289 OSM_LOG_EXIT(&p_osmt->log);
293 /**********************************************************************
294 * GET A SINGLE PORT INFO BY NODE LID AND PORT NUMBER
295 **********************************************************************/
297 osmt_query_slvl_map(IN osmtest_t * const p_osmt,
298 IN ib_net16_t const lid,
299 IN uint8_t const out_port_num,
300 IN uint8_t const in_port_num, IN FILE * fh)
302 osmtest_req_context_t context;
303 ib_api_status_t status = IB_SUCCESS;
304 osmv_user_query_t user;
305 osmv_query_req_t req;
306 ib_slvl_table_record_t record, *p_rec;
308 OSM_LOG_ENTER(&p_osmt->log);
310 OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
311 "Getting SLtoVL Map Table for out-port with LID 0x%X Num:0x%X from In-Port:0x%X\n",
312 cl_ntoh16(lid), out_port_num, in_port_num);
315 * Do a blocking query for this record in the subnet.
316 * The result is returned in the result field of the caller's
319 * The query structures are locals.
321 memset(&req, 0, sizeof(req));
322 memset(&user, 0, sizeof(user));
323 memset(&context, 0, sizeof(context));
325 context.p_osmt = p_osmt;
328 record.in_port_num = in_port_num;
329 record.out_port_num = out_port_num;
330 user.p_attr = &record;
332 req.query_type = OSMV_QUERY_SLVL_BY_LID_AND_PORTS;
333 req.timeout_ms = p_osmt->opt.transaction_timeout;
334 req.retry_cnt = p_osmt->opt.retry_count;
335 req.flags = OSM_SA_FLAGS_SYNC;
336 req.query_context = &context;
337 req.pfn_query_cb = osmtest_query_res_cb;
338 req.p_query_input = &user;
341 status = osmv_query_sa(p_osmt->h_bind, &req);
343 if (status != IB_SUCCESS) {
344 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0469: "
345 "ib_query failed (%s)\n", ib_get_err_str(status));
349 status = context.result.status;
351 if (status != IB_SUCCESS) {
352 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0470: "
353 "ib_query failed (%s)\n", ib_get_err_str(status));
355 if (status == IB_REMOTE_ERROR) {
356 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
357 "Remote error = %s\n",
358 ib_get_mad_status_str(osm_madw_get_mad_ptr
366 p_rec = osmv_get_query_result(context.result.p_result_madw, 0);
368 osmtest_write_slvl_map_table(p_osmt, fh, p_rec);
373 * Return the IB query MAD to the pool as necessary.
375 if (context.result.p_result_madw != NULL) {
376 osm_mad_pool_put(&p_osmt->mad_pool,
377 context.result.p_result_madw);
378 context.result.p_result_madw = NULL;
381 OSM_LOG_EXIT(&p_osmt->log);
385 static ib_api_status_t
386 osmt_query_all_ports_slvl_map(IN osmtest_t * const p_osmt, IN FILE * fh)
388 cl_status_t status = CL_SUCCESS;
391 uint8_t in_port, anyErr = 0, num_ports;
393 const cl_qmap_t *p_node_tbl;
395 OSM_LOG_ENTER(&p_osmt->log);
398 * Go over all ports that exist in the subnet
399 * get the relevant SLtoVLs
402 OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
403 "Obtaining ALL Ports (to other ports) SLtoVL Maps\n");
405 p_tbl = &p_osmt->exp_subn.port_key_tbl;
406 p_node_tbl = &p_osmt->exp_subn.node_lid_tbl;
408 p_src_port = (port_t *) cl_qmap_head(p_tbl);
410 while (p_src_port != (port_t *) cl_qmap_end(p_tbl)) {
412 /* HACK we use capability_mask to know diff a CA port from switch port */
413 if (p_src_port->rec.port_info.capability_mask) {
414 /* this is an hca port */
415 /* NOTE to comply we must set port number to 0 and the SA should figure it out */
416 /* since it is a CA port */
418 osmt_query_slvl_map(p_osmt, p_src_port->rec.lid, 0,
420 if (status != IB_SUCCESS) {
421 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0471: "
422 "Failed to get Lid:0x%X In-Port:0x%X Out-Port:0x%X(%s)\n",
423 cl_ntoh16(p_src_port->rec.lid), 0, 0,
424 ib_get_err_str(status));
428 /* this is a switch port */
431 (node_t *) cl_qmap_get(p_node_tbl,
432 p_src_port->rec.lid);
433 if (p_node == (node_t *) cl_qmap_end(p_node_tbl)) {
434 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0472: "
435 "Failed to get Node by Lid:0x%X\n",
436 p_src_port->rec.lid);
440 num_ports = p_node->rec.node_info.num_ports;
442 for (in_port = 1; in_port <= num_ports; in_port++) {
444 osmt_query_slvl_map(p_osmt,
447 port_num, in_port, fh);
448 if (status != IB_SUCCESS) {
449 OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
451 "Failed to get Lid:0x%X In-Port:0x%X Out-Port:0x%X (%s)\n",
452 cl_ntoh16(p_src_port->rec.lid),
453 p_src_port->rec.port_num,
455 ib_get_err_str(status));
461 p_src_port = (port_t *) cl_qmap_next(&p_src_port->map_item);
465 OSM_LOG_EXIT(&p_osmt->log);
473 * Run a vl arbitration queries and sl2vl maps queries flow:
475 * - for each physical port on the network - obtain the VL Arb
476 * - for each CA physical port obtain its SLtoVL Map
477 * - for each SW physical port (out) obtain the SLtoVL Map to each other port
479 * - Try get with multiple results
481 * - Try providing non existing port
484 osmt_run_slvl_and_vlarb_records_flow(IN osmtest_t * const p_osmt)
486 ib_api_status_t status;
491 OSM_LOG_ENTER(&p_osmt->log);
493 fh = fopen("qos.txt", "w");
495 /* go over all ports in the subnet */
496 status = osmt_query_all_ports_vl_arb(p_osmt, fh);
497 if (status != IB_SUCCESS) {
501 status = osmt_query_all_ports_slvl_map(p_osmt, fh);
502 if (status != IB_SUCCESS) {
506 /* If LMC > 0, test non base LID SA QoS Record requests */
508 osmtest_get_local_port_lmc(p_osmt, p_osmt->local_port.lid, &lmc);
509 if (status != IB_SUCCESS)
513 test_lid = cl_ntoh16(p_osmt->local_port.lid + 1);
515 status = osmt_query_vl_arb(p_osmt, test_lid, 0, 1, NULL);
516 if (status != IB_SUCCESS)
519 status = osmt_query_slvl_map(p_osmt, test_lid, 0, 0, NULL);
520 if (status != IB_SUCCESS)
526 OSM_LOG_EXIT(&p_osmt->log);