1 /* 2 * Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 * 32 */ 33 34 /* 35 * Abstract: 36 * Implementation of osm_mlnx_epi_rcv_t. 37 * This object represents the MLNX ExtendedPortInfo Receiver object. 38 * This object is part of the opensm family of objects. 39 */ 40 41 #if HAVE_CONFIG_H 42 # include <config.h> 43 #endif /* HAVE_CONFIG_H */ 44 45 #include <string.h> 46 #include <stdlib.h> 47 #include <iba/ib_types.h> 48 #include <complib/cl_qmap.h> 49 #include <complib/cl_passivelock.h> 50 #include <complib/cl_debug.h> 51 #include <opensm/osm_file_ids.h> 52 #define FILE_ID OSM_FILE_MLNX_EXT_PORT_INFO_RCV_C 53 #include <vendor/osm_vendor_api.h> 54 #include <opensm/osm_madw.h> 55 #include <opensm/osm_log.h> 56 #include <opensm/osm_node.h> 57 #include <opensm/osm_subnet.h> 58 #include <opensm/osm_mad_pool.h> 59 #include <opensm/osm_msgdef.h> 60 #include <opensm/osm_helper.h> 61 #include <opensm/osm_opensm.h> 62 63 void osm_mlnx_epi_rcv_process(IN void *context, IN void *data) 64 { 65 osm_sm_t *sm = context; 66 osm_madw_t *p_madw = data; 67 ib_mlnx_ext_port_info_t *p_pi; 68 ib_smp_t *p_smp; 69 osm_port_t *p_port; 70 osm_physp_t *p_physp; 71 osm_node_t *p_node; 72 osm_pi_context_t *p_context; 73 ib_net64_t port_guid, node_guid; 74 uint8_t port_num, portnum, start_port = 1; 75 76 OSM_LOG_ENTER(sm->p_log); 77 78 CL_ASSERT(sm); 79 CL_ASSERT(p_madw); 80 81 p_smp = osm_madw_get_smp_ptr(p_madw); 82 p_context = osm_madw_get_pi_context_ptr(p_madw); 83 p_pi = ib_smp_get_payload_ptr(p_smp); 84 85 CL_ASSERT(p_smp->attr_id == IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO); 86 87 port_num = (uint8_t) cl_ntoh32(p_smp->attr_mod); 88 89 port_guid = p_context->port_guid; 90 node_guid = p_context->node_guid; 91 92 osm_dump_mlnx_ext_port_info_v2(sm->p_log, node_guid, port_guid, port_num, 93 p_pi, FILE_ID, OSM_LOG_DEBUG); 94 95 CL_PLOCK_EXCL_ACQUIRE(sm->p_lock); 96 p_port = osm_get_port_by_guid(sm->p_subn, port_guid); 97 if (!p_port) { 98 CL_PLOCK_RELEASE(sm->p_lock); 99 OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F06: " 100 "No port object for port with GUID 0x%" PRIx64 101 "\n\t\t\t\tfor parent node GUID 0x%" PRIx64 102 ", TID 0x%" PRIx64 "\n", 103 cl_ntoh64(port_guid), 104 cl_ntoh64(node_guid), cl_ntoh64(p_smp->trans_id)); 105 goto Exit; 106 } 107 108 p_node = p_port->p_node; 109 CL_ASSERT(p_node); 110 111 if (!(cl_ntoh16(p_smp->status) & 0x7fff)) { 112 if (port_num != 255) { 113 p_physp = osm_node_get_physp_ptr(p_node, port_num); 114 CL_ASSERT(p_physp); 115 p_physp->ext_port_info = *p_pi; 116 } else { 117 /* Handle all ports on set/set resp */ 118 if (p_node->sw && 119 ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info)) 120 start_port = 0; 121 122 for (portnum = start_port; 123 portnum < osm_node_get_num_physp(p_node); 124 portnum++) { 125 p_physp = osm_node_get_physp_ptr(p_node, portnum); 126 CL_ASSERT(p_physp); 127 p_physp->ext_port_info = *p_pi; 128 } 129 } 130 } else 131 OSM_LOG(sm->p_log, OSM_LOG_DEBUG, 132 "MAD status 0x%x received\n", 133 cl_ntoh16(p_smp->status) & 0x7fff); 134 135 CL_PLOCK_RELEASE(sm->p_lock); 136 137 Exit: 138 /* 139 Release the lock before jumping here!! 140 */ 141 OSM_LOG_EXIT(sm->p_log); 142 } 143