| /* |
| * 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 <config.h> |
| |
| #include <string.h> |
| #include <stdio.h> |
| #include <inttypes.h> |
| |
| #include <infiniband/umad.h> |
| |
| #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; |
| } |