/* * Copyright (c) 2014 Intel Corporation, All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #include #include #include #include #include #define UNLIKELY_MGMT_CLASS 0x2F #define UNLIKELY_RMPP_MGMT_CLASS 0x4F static int test_failures = 0; /** ========================================================================= * Stolen from OpenSM's register */ static int set_bit(int nr, void *method_mask) { long mask, *addr = method_mask; int retval; addr += nr / (8 * sizeof(long)); mask = (1UL) << (nr % (8 * sizeof(long))); retval = (mask & *addr) != 0; *addr |= mask; return retval; } static void set_bit64(int b, uint64_t *buf) { uint64_t mask; uint64_t *addr = buf; addr += b >> 6; mask = 1ULL << (b & 0x3f); *addr |= mask; } static void dump_reg_attr(struct umad_reg_attr *reg_attr) { printf("\nmgmt_class %u\n" "mgmt_class_version %u\n" "flags 0x%08x\n" "method_mask 0x%016"PRIx64" %016"PRIx64"\n" "oui 0x%06x\n" "rmpp_version %u\n\n", reg_attr->mgmt_class, reg_attr->mgmt_class_version, reg_attr->flags, reg_attr->method_mask[1], reg_attr->method_mask[0], reg_attr->oui, reg_attr->rmpp_version); } static int open_test_device(void) { int fd = umad_open_port(NULL, 0); if (fd < 0) { printf("\n *****\nOpen Port Failure... Aborting\n"); printf(" Ensure you have an HCA to test against.\n"); exit(0); } return fd; } static void test_register(void) { int agent_id; long method_mask[16 / sizeof(long)]; uint32_t class_oui = 0x001405; /* OPENIB_OUI */ uint8_t oui[3]; int fd; printf("\n old register test ... "); fd = open_test_device(); memset(&method_mask, 0, sizeof(method_mask)); set_bit( 1, &method_mask); set_bit(63, &method_mask); set_bit(64, &method_mask); // equal to this with the new register //reg_attr.method_mask[0] = 0x8000000000000002ULL; //reg_attr.method_mask[1] = 0x0000000000000001ULL; agent_id = umad_register(fd, UNLIKELY_MGMT_CLASS, 0x1, 0x00, method_mask); if (agent_id < 0) { printf("\n umad_register Failure, agent_id %d\n", agent_id); printf("\n umad_register(fd, 0x01, 0x1, 0x00, method_mask);\n"); test_failures++; } else { printf(" PASS\n"); umad_unregister(fd, agent_id); } printf("\n old register_oui test ... "); oui[0] = (class_oui >> 16) & 0xff; oui[1] = (class_oui >> 8) & 0xff; oui[2] = class_oui & 0xff; agent_id = umad_register_oui(fd, UNLIKELY_RMPP_MGMT_CLASS, 0x1, oui, method_mask); if (agent_id < 0) { printf("\n umad_register_oui Failure, agent_id %d\n", agent_id); printf("\n umad_register(fd, 0x30, 0x1, oui, method_mask);\n"); test_failures++; } else { printf(" PASS\n"); umad_unregister(fd, agent_id); } umad_close_port(fd); } static void test_fall_back(void) { int rc = 0; struct umad_reg_attr reg_attr; uint32_t agent_id; int fd; fd = open_test_device(); memset(®_attr, 0, sizeof(reg_attr)); reg_attr.mgmt_class = UNLIKELY_MGMT_CLASS; reg_attr.mgmt_class_version = 0x1; reg_attr.oui = 0x001405; /* OPENIB_OUI */ //reg_attr.method_mask[0] = 0x8000000000000002ULL; //reg_attr.method_mask[1] = 0x0000000000000001ULL; set_bit64( 1, (uint64_t *)®_attr.method_mask); set_bit64(63, (uint64_t *)®_attr.method_mask); set_bit64(64, (uint64_t *)®_attr.method_mask); printf("\n umad_register2 fall back (set_bit) ... "); rc = umad_register2(fd, ®_attr, &agent_id); if (rc != 0) { printf("\n umad_register2 failed to fall back. rc = %d\n", rc); dump_reg_attr(®_attr); test_failures++; } else { printf(" PASS\n"); umad_unregister(fd, agent_id); } reg_attr.method_mask[0] = 0x8000000000000002ULL; reg_attr.method_mask[1] = 0x0000000000000001ULL; printf("\n umad_register2 fall back ... "); rc = umad_register2(fd, ®_attr, &agent_id); if (rc != 0) { printf("\n umad_register2 failed to fall back. rc = %d\n", rc); dump_reg_attr(®_attr); test_failures++; } else { printf(" PASS\n"); umad_unregister(fd, agent_id); } umad_close_port(fd); } int main(int argc, char *argv[]) { //umad_debug(1); printf("\n *****\nStart compatibility tests\n"); test_register(); test_fall_back(); printf("\n *******************\n"); printf(" umad_reg2_compat had %d failures\n", test_failures); printf(" *******************\n"); return test_failures; }