1 /* 2 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved. 4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5 * 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: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 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. 24 * 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 32 * SOFTWARE. 33 * 34 */ 35 36 /* 37 * Abstract: 38 * Implementation of osm_physp_t. 39 * This object represents an Infiniband Port. 40 * This object is part of the opensm family of objects. 41 */ 42 43 #if HAVE_CONFIG_H 44 # include <config.h> 45 #endif /* HAVE_CONFIG_H */ 46 47 #include <stdlib.h> 48 #include <string.h> 49 #include <complib/cl_debug.h> 50 #include <iba/ib_types.h> 51 #include <opensm/osm_file_ids.h> 52 #define FILE_ID OSM_FILE_PORT_C 53 #include <opensm/osm_port.h> 54 #include <opensm/osm_node.h> 55 #include <opensm/osm_madw.h> 56 #include <opensm/osm_switch.h> 57 #include <opensm/osm_db_pack.h> 58 #include <opensm/osm_sm.h> 59 60 void osm_physp_construct(IN osm_physp_t * p_physp) 61 { 62 memset(p_physp, 0, sizeof(*p_physp)); 63 osm_dr_path_construct(&p_physp->dr_path); 64 cl_ptr_vector_construct(&p_physp->slvl_by_port); 65 osm_pkey_tbl_construct(&p_physp->pkeys); 66 } 67 68 void osm_physp_destroy(IN osm_physp_t * p_physp) 69 { 70 size_t num_slvl, i; 71 72 /* the physp might be uninitialized */ 73 if (p_physp->port_guid) { 74 if (p_physp->p_guids) 75 free(p_physp->p_guids); 76 77 /* free the SL2VL Tables */ 78 num_slvl = cl_ptr_vector_get_size(&p_physp->slvl_by_port); 79 for (i = 0; i < num_slvl; i++) 80 free(cl_ptr_vector_get(&p_physp->slvl_by_port, i)); 81 cl_ptr_vector_destroy(&p_physp->slvl_by_port); 82 83 /* free the P_Key Tables */ 84 osm_pkey_tbl_destroy(&p_physp->pkeys); 85 86 memset(p_physp, 0, sizeof(*p_physp)); 87 osm_dr_path_construct(&p_physp->dr_path); /* clear dr_path */ 88 } 89 } 90 91 void osm_physp_init(IN osm_physp_t * p_physp, IN ib_net64_t port_guid, 92 IN uint8_t port_num, IN const struct osm_node *p_node, 93 IN osm_bind_handle_t h_bind, IN uint8_t hop_count, 94 IN const uint8_t * p_initial_path) 95 { 96 uint16_t num_slvl, i; 97 ib_slvl_table_t *p_slvl; 98 99 CL_ASSERT(p_node); 100 101 osm_physp_construct(p_physp); 102 p_physp->port_guid = port_guid; 103 p_physp->port_num = port_num; 104 p_physp->healthy = TRUE; 105 p_physp->need_update = 2; 106 p_physp->p_node = (struct osm_node *)p_node; 107 108 osm_dr_path_init(&p_physp->dr_path, hop_count, p_initial_path); 109 110 /* allocate enough SL2VL tables */ 111 if (osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH) 112 /* we need node num ports + 1 SL2VL tables */ 113 num_slvl = osm_node_get_num_physp(p_node) + 1; 114 else 115 /* An end node - we need only one SL2VL */ 116 num_slvl = 1; 117 118 cl_ptr_vector_init(&p_physp->slvl_by_port, num_slvl, 1); 119 for (i = 0; i < num_slvl; i++) { 120 p_slvl = (ib_slvl_table_t *) malloc(sizeof(ib_slvl_table_t)); 121 if (!p_slvl) 122 break; 123 memset(p_slvl, 0, sizeof(ib_slvl_table_t)); 124 cl_ptr_vector_set(&p_physp->slvl_by_port, i, p_slvl); 125 } 126 127 /* initialize the pkey table */ 128 osm_pkey_tbl_init(&p_physp->pkeys); 129 } 130 131 void osm_port_delete(IN OUT osm_port_t ** pp_port) 132 { 133 free(*pp_port); 134 *pp_port = NULL; 135 } 136 137 osm_port_t *osm_port_new(IN const ib_node_info_t * p_ni, 138 IN osm_node_t * p_parent_node) 139 { 140 osm_port_t *p_port; 141 ib_net64_t port_guid; 142 osm_physp_t *p_physp; 143 uint8_t port_num; 144 145 p_port = malloc(sizeof(*p_port)); 146 if (!p_port) 147 return NULL; 148 149 memset(p_port, 0, sizeof(*p_port)); 150 cl_qlist_init(&p_port->mcm_list); 151 p_port->p_node = (struct osm_node *)p_parent_node; 152 port_guid = p_ni->port_guid; 153 p_port->guid = port_guid; 154 port_num = p_ni->node_type == IB_NODE_TYPE_SWITCH ? 155 0 : ib_node_info_get_local_port_num(p_ni); 156 157 /* 158 Get the pointers to the physical node objects "owned" by this 159 logical port GUID. 160 For switches, port '0' is owned; for HCA's and routers, 161 only the singular part that has this GUID is owned. 162 */ 163 p_physp = osm_node_get_physp_ptr(p_parent_node, port_num); 164 if (!p_physp) 165 return NULL; 166 167 CL_ASSERT(port_guid == osm_physp_get_port_guid(p_physp)); 168 p_port->p_physp = p_physp; 169 170 return p_port; 171 } 172 173 void osm_port_get_lid_range_ho(IN const osm_port_t * p_port, 174 IN uint16_t * p_min_lid, IN uint16_t * p_max_lid) 175 { 176 uint8_t lmc; 177 178 *p_min_lid = cl_ntoh16(osm_port_get_base_lid(p_port)); 179 lmc = osm_port_get_lmc(p_port); 180 *p_max_lid = (uint16_t) (*p_min_lid + (1 << lmc) - 1); 181 } 182 183 uint8_t osm_physp_calc_link_mtu(IN osm_log_t * p_log, 184 IN const osm_physp_t * p_physp, 185 IN uint8_t current_mtu) 186 { 187 const osm_physp_t *p_remote_physp; 188 uint8_t mtu; 189 uint8_t remote_mtu; 190 191 OSM_LOG_ENTER(p_log); 192 193 p_remote_physp = osm_physp_get_remote(p_physp); 194 if (p_remote_physp) { 195 /* use the available MTU */ 196 mtu = ib_port_info_get_mtu_cap(&p_physp->port_info); 197 198 remote_mtu = 199 ib_port_info_get_mtu_cap(&p_remote_physp->port_info); 200 201 OSM_LOG(p_log, OSM_LOG_DEBUG, 202 "Remote port 0x%016" PRIx64 " port = %u : " 203 "MTU = %u. This Port MTU: %u\n", 204 cl_ntoh64(osm_physp_get_port_guid(p_remote_physp)), 205 osm_physp_get_port_num(p_remote_physp), 206 remote_mtu, mtu); 207 208 if (mtu != remote_mtu) { 209 if (mtu > remote_mtu) 210 mtu = remote_mtu; 211 if (mtu != current_mtu) 212 OSM_LOG(p_log, OSM_LOG_VERBOSE, 213 "MTU mismatch between ports." 214 "\n\t\t\t\tPort 0x%016" PRIx64 ", port %u" 215 " and port 0x%016" PRIx64 ", port %u." 216 "\n\t\t\t\tUsing lower MTU of %u\n", 217 cl_ntoh64(osm_physp_get_port_guid(p_physp)), 218 osm_physp_get_port_num(p_physp), 219 cl_ntoh64(osm_physp_get_port_guid 220 (p_remote_physp)), 221 osm_physp_get_port_num(p_remote_physp), mtu); 222 } 223 } else 224 mtu = ib_port_info_get_neighbor_mtu(&p_physp->port_info); 225 226 if (mtu == 0) { 227 OSM_LOG(p_log, OSM_LOG_DEBUG, "ERR 4101: " 228 "Invalid MTU = 0. Forcing correction to 256\n"); 229 mtu = 1; 230 } 231 232 OSM_LOG_EXIT(p_log); 233 return mtu; 234 } 235 236 uint8_t osm_physp_calc_link_op_vls(IN osm_log_t * p_log, 237 IN const osm_subn_t * p_subn, 238 IN const osm_physp_t * p_physp, 239 IN uint8_t current_op_vls) 240 { 241 const osm_physp_t *p_remote_physp; 242 uint8_t op_vls; 243 uint8_t remote_op_vls; 244 245 OSM_LOG_ENTER(p_log); 246 247 p_remote_physp = osm_physp_get_remote(p_physp); 248 if (p_remote_physp) { 249 /* use the available VLCap */ 250 op_vls = ib_port_info_get_vl_cap(&p_physp->port_info); 251 252 remote_op_vls = 253 ib_port_info_get_vl_cap(&p_remote_physp->port_info); 254 255 OSM_LOG(p_log, OSM_LOG_DEBUG, 256 "Remote port 0x%016" PRIx64 " port = 0x%X : " 257 "VL_CAP = %u. This port VL_CAP = %u\n", 258 cl_ntoh64(osm_physp_get_port_guid(p_remote_physp)), 259 osm_physp_get_port_num(p_remote_physp), 260 remote_op_vls, op_vls); 261 262 if (op_vls != remote_op_vls) { 263 if (op_vls > remote_op_vls) 264 op_vls = remote_op_vls; 265 if (op_vls != current_op_vls) 266 OSM_LOG(p_log, OSM_LOG_VERBOSE, 267 "OP_VLS mismatch between ports." 268 "\n\t\t\t\tPort 0x%016" PRIx64 ", port 0x%X" 269 " and port 0x%016" PRIx64 ", port 0x%X." 270 "\n\t\t\t\tUsing lower OP_VLS of %u\n", 271 cl_ntoh64(osm_physp_get_port_guid(p_physp)), 272 osm_physp_get_port_num(p_physp), 273 cl_ntoh64(osm_physp_get_port_guid 274 (p_remote_physp)), 275 osm_physp_get_port_num(p_remote_physp), op_vls); 276 } 277 } else 278 op_vls = ib_port_info_get_op_vls(&p_physp->port_info); 279 280 if (op_vls == 0) { 281 /* for non compliant implementations */ 282 OSM_LOG(p_log, OSM_LOG_VERBOSE, 283 "Invalid OP_VLS = 0. Forcing correction to 1 (VL0)\n"); 284 op_vls = 1; 285 } 286 287 /* support user limitation of max_op_vls */ 288 if (op_vls > p_subn->opt.max_op_vls) 289 op_vls = p_subn->opt.max_op_vls; 290 291 OSM_LOG_EXIT(p_log); 292 return op_vls; 293 } 294 295 static inline uint64_t ptr_to_key(void const *p) 296 { 297 uint64_t k = 0; 298 299 memcpy(&k, p, sizeof(void *)); 300 return k; 301 } 302 303 static inline void *key_to_ptr(uint64_t k) 304 { 305 void *p = 0; 306 307 memcpy(&p, &k, sizeof(void *)); 308 return p; 309 } 310 311 /********************************************************************** 312 Traverse the fabric from the SM node following the DR path given and 313 add every phys port traversed to the map. Avoid tracking the first and 314 last phys ports (going into the first switch and into the target port). 315 **********************************************************************/ 316 static cl_status_t physp_get_dr_physp_set(IN osm_log_t * p_log, 317 IN osm_subn_t const *p_subn, 318 IN osm_dr_path_t const *p_path, 319 OUT cl_map_t * p_physp_map) 320 { 321 osm_port_t *p_port; 322 osm_physp_t *p_physp; 323 osm_node_t *p_node; 324 uint8_t hop; 325 cl_status_t status = CL_SUCCESS; 326 327 OSM_LOG_ENTER(p_log); 328 329 /* find the OSM node */ 330 p_port = osm_get_port_by_guid(p_subn, p_subn->sm_port_guid); 331 if (!p_port) { 332 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 4103: " 333 "Failed to find the SM own port by guid\n"); 334 status = CL_ERROR; 335 goto Exit; 336 } 337 338 /* get the node of the SM */ 339 p_node = p_port->p_node; 340 341 /* 342 traverse the path adding the nodes to the table 343 start after the first dummy hop and stop just before the 344 last one 345 */ 346 for (hop = 1; hop < p_path->hop_count - 1; hop++) { 347 /* go out using the phys port of the path */ 348 p_physp = osm_node_get_physp_ptr(p_node, p_path->path[hop]); 349 350 /* make sure we got a valid port and it has a remote port */ 351 if (!p_physp) { 352 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 4104: " 353 "DR Traversal stopped on invalid port at hop:%u\n", 354 hop); 355 status = CL_ERROR; 356 goto Exit; 357 } 358 359 /* we track the ports we go out along the path */ 360 if (hop > 1) 361 cl_map_insert(p_physp_map, ptr_to_key(p_physp), NULL); 362 363 OSM_LOG(p_log, OSM_LOG_DEBUG, 364 "Traversed through node: 0x%016" PRIx64 365 " port:%u\n", 366 cl_ntoh64(p_node->node_info.node_guid), 367 p_path->path[hop]); 368 369 if (!(p_physp = osm_physp_get_remote(p_physp))) { 370 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 4106: " 371 "DR Traversal stopped on missing remote physp at hop:%u\n", 372 hop); 373 status = CL_ERROR; 374 goto Exit; 375 } 376 377 p_node = osm_physp_get_node_ptr(p_physp); 378 } 379 380 Exit: 381 OSM_LOG_EXIT(p_log); 382 return status; 383 } 384 385 static void physp_update_new_dr_path(IN osm_physp_t const *p_dest_physp, 386 IN cl_map_t * p_visited_map, 387 IN osm_bind_handle_t * h_bind) 388 { 389 cl_list_t tmpPortsList; 390 osm_physp_t *p_physp, *p_src_physp = NULL; 391 uint8_t path_array[IB_SUBNET_PATH_HOPS_MAX]; 392 uint8_t i = 0; 393 osm_dr_path_t *p_dr_path; 394 395 cl_list_construct(&tmpPortsList); 396 cl_list_init(&tmpPortsList, 10); 397 398 cl_list_insert_head(&tmpPortsList, p_dest_physp); 399 /* get the output port where we need to come from */ 400 p_physp = (osm_physp_t *) cl_map_get(p_visited_map, 401 ptr_to_key(p_dest_physp)); 402 while (p_physp != NULL) { 403 cl_list_insert_head(&tmpPortsList, p_physp); 404 /* get the input port through where we reached the output port */ 405 p_src_physp = p_physp; 406 p_physp = (osm_physp_t *) cl_map_get(p_visited_map, 407 ptr_to_key(p_physp)); 408 /* if we reached a null p_physp - this means we are at the begining 409 of the path. Break. */ 410 if (p_physp == NULL) 411 break; 412 /* get the output port */ 413 p_physp = (osm_physp_t *) cl_map_get(p_visited_map, 414 ptr_to_key(p_physp)); 415 } 416 417 memset(path_array, 0, sizeof(path_array)); 418 p_physp = (osm_physp_t *) cl_list_remove_head(&tmpPortsList); 419 while (p_physp != NULL) { 420 i++; 421 path_array[i] = p_physp->port_num; 422 p_physp = (osm_physp_t *) cl_list_remove_head(&tmpPortsList); 423 } 424 if (p_src_physp) { 425 p_dr_path = osm_physp_get_dr_path_ptr(p_src_physp); 426 osm_dr_path_init(p_dr_path, i, path_array); 427 } 428 429 cl_list_destroy(&tmpPortsList); 430 } 431 432 void osm_physp_replace_dr_path_with_alternate_dr_path(IN osm_log_t * p_log, 433 IN osm_subn_t const 434 *p_subn, IN osm_physp_t const 435 *p_dest_physp, 436 IN osm_bind_handle_t * 437 h_bind) 438 { 439 cl_map_t physp_map; 440 cl_map_t visited_map; 441 osm_dr_path_t *p_dr_path; 442 cl_list_t *p_currPortsList; 443 cl_list_t *p_nextPortsList; 444 osm_port_t *p_port; 445 osm_physp_t *p_physp, *p_remote_physp; 446 ib_net64_t port_guid; 447 boolean_t next_list_is_full = TRUE, reached_dest = FALSE; 448 uint8_t num_ports, port_num; 449 450 p_nextPortsList = (cl_list_t *) malloc(sizeof(cl_list_t)); 451 if (!p_nextPortsList) 452 return; 453 454 /* 455 initialize the map of all port participating in current dr path 456 not including first and last switches 457 */ 458 cl_map_construct(&physp_map); 459 cl_map_init(&physp_map, 4); 460 cl_map_construct(&visited_map); 461 cl_map_init(&visited_map, 4); 462 p_dr_path = osm_physp_get_dr_path_ptr(p_dest_physp); 463 physp_get_dr_physp_set(p_log, p_subn, p_dr_path, &physp_map); 464 465 /* 466 BFS from OSM port until we find the target physp but avoid 467 going through mapped ports 468 */ 469 cl_list_construct(p_nextPortsList); 470 cl_list_init(p_nextPortsList, 10); 471 472 port_guid = p_subn->sm_port_guid; 473 474 CL_ASSERT(port_guid); 475 476 p_port = osm_get_port_by_guid(p_subn, port_guid); 477 if (!p_port) { 478 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 4105: No SM port object\n"); 479 goto Exit; 480 } 481 482 /* 483 HACK: We are assuming SM is running on HCA, so when getting the default 484 port we'll get the port connected to the rest of the subnet. If SM is 485 running on SWITCH - we should try to get a dr path from all switch ports. 486 */ 487 p_physp = p_port->p_physp; 488 489 CL_ASSERT(p_physp); 490 491 cl_list_insert_tail(p_nextPortsList, p_physp); 492 493 while (next_list_is_full == TRUE) { 494 next_list_is_full = FALSE; 495 p_currPortsList = p_nextPortsList; 496 p_nextPortsList = (cl_list_t *) malloc(sizeof(cl_list_t)); 497 if (!p_nextPortsList) { 498 p_nextPortsList = p_currPortsList; 499 goto Exit; 500 } 501 cl_list_construct(p_nextPortsList); 502 cl_list_init(p_nextPortsList, 10); 503 p_physp = (osm_physp_t *) cl_list_remove_head(p_currPortsList); 504 while (p_physp != NULL) { 505 /* If we are in a switch - need to go out through all 506 the other physical ports of the switch */ 507 num_ports = osm_node_get_num_physp(p_physp->p_node); 508 509 for (port_num = 1; port_num < num_ports; port_num++) { 510 if (osm_node_get_type(p_physp->p_node) == 511 IB_NODE_TYPE_SWITCH) 512 p_remote_physp = 513 osm_node_get_physp_ptr(p_physp-> 514 p_node, 515 port_num); 516 else 517 /* this is HCA or router - the remote port is just the port connected 518 on the other side */ 519 p_remote_physp = 520 p_physp->p_remote_physp; 521 522 /* 523 make sure that all of the following occurred: 524 1. The port isn't NULL 525 2. This is not the port we came from 526 3. The port is not in the physp_map 527 4. This port haven't been visited before 528 */ 529 if (p_remote_physp && 530 p_remote_physp != p_physp && 531 cl_map_get(&physp_map, 532 ptr_to_key(p_remote_physp)) 533 == NULL 534 && cl_map_get(&visited_map, 535 ptr_to_key 536 (p_remote_physp)) == NULL) { 537 /* Insert the port into the visited_map, and save its source port */ 538 cl_map_insert(&visited_map, 539 ptr_to_key 540 (p_remote_physp), 541 p_physp); 542 543 /* Is this the p_dest_physp? */ 544 if (p_remote_physp == p_dest_physp) { 545 /* update the new dr path */ 546 physp_update_new_dr_path 547 (p_dest_physp, &visited_map, 548 h_bind); 549 reached_dest = TRUE; 550 break; 551 } 552 553 /* add the p_remote_physp to the nextPortsList */ 554 cl_list_insert_tail(p_nextPortsList, 555 p_remote_physp); 556 next_list_is_full = TRUE; 557 } 558 } 559 560 p_physp = (osm_physp_t *) 561 cl_list_remove_head(p_currPortsList); 562 if (reached_dest == TRUE) { 563 /* free the rest of the currPortsList */ 564 while (p_physp != NULL) 565 p_physp = (osm_physp_t *) 566 cl_list_remove_head 567 (p_currPortsList); 568 /* free the nextPortsList, if items were added to it */ 569 p_physp = (osm_physp_t *) 570 cl_list_remove_head(p_nextPortsList); 571 while (p_physp != NULL) 572 p_physp = (osm_physp_t *) 573 cl_list_remove_head 574 (p_nextPortsList); 575 next_list_is_full = FALSE; 576 } 577 } 578 cl_list_destroy(p_currPortsList); 579 free(p_currPortsList); 580 } 581 582 /* cleanup */ 583 Exit: 584 cl_list_destroy(p_nextPortsList); 585 free(p_nextPortsList); 586 cl_map_destroy(&physp_map); 587 cl_map_destroy(&visited_map); 588 } 589 590 boolean_t osm_link_is_healthy(IN const osm_physp_t * p_physp) 591 { 592 osm_physp_t *p_remote_physp; 593 594 CL_ASSERT(p_physp); 595 p_remote_physp = p_physp->p_remote_physp; 596 if (p_remote_physp != NULL) 597 return ((p_physp->healthy) & (p_remote_physp->healthy)); 598 /* the other side is not known - consider the link as healthy */ 599 return TRUE; 600 } 601 602 void osm_physp_set_pkey_tbl(IN osm_log_t * p_log, IN const osm_subn_t * p_subn, 603 IN osm_physp_t * p_physp, 604 IN ib_pkey_table_t * p_pkey_tbl, 605 IN uint16_t block_num, 606 IN boolean_t is_set) 607 { 608 uint16_t max_blocks; 609 610 CL_ASSERT(p_pkey_tbl); 611 /* 612 (14.2.5.7) - the block number valid values are 0-2047, and are 613 further limited by the size of the P_Key table specified by 614 the PartitionCap on the node. 615 */ 616 if (!p_physp->p_node->sw || p_physp->port_num == 0) 617 /* 618 The maximum blocks is defined in the node info: partition cap 619 for CA, router, and switch management ports. 620 */ 621 max_blocks = 622 (cl_ntoh16(p_physp->p_node->node_info.partition_cap) + 623 IB_NUM_PKEY_ELEMENTS_IN_BLOCK - 1) 624 / IB_NUM_PKEY_ELEMENTS_IN_BLOCK; 625 else 626 /* 627 This is a switch, and not a management port. The maximum 628 blocks is defined in the switch info: partition enforcement 629 cap. 630 */ 631 max_blocks = 632 (cl_ntoh16(p_physp->p_node->sw->switch_info.enforce_cap) + 633 IB_NUM_PKEY_ELEMENTS_IN_BLOCK - 634 1) / IB_NUM_PKEY_ELEMENTS_IN_BLOCK; 635 636 if (block_num >= max_blocks) { 637 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 4108: " 638 "Got illegal update for block number:%u max:%u " 639 "for GUID: %" PRIx64 " port number:%u\n", 640 block_num, max_blocks, 641 cl_ntoh64(p_physp->p_node->node_info.node_guid), 642 p_physp->port_num); 643 return; 644 } 645 646 /* decrement block received counter */ 647 if(!is_set) 648 p_physp->pkeys.rcv_blocks_cnt--; 649 osm_pkey_tbl_set(&p_physp->pkeys, block_num, p_pkey_tbl, 650 p_subn->opt.allow_both_pkeys); 651 } 652 653 osm_alias_guid_t *osm_alias_guid_new(IN const ib_net64_t alias_guid, 654 IN osm_port_t *p_base_port) 655 { 656 osm_alias_guid_t *p_alias_guid; 657 658 p_alias_guid = calloc(1, sizeof(*p_alias_guid)); 659 if (p_alias_guid) { 660 p_alias_guid->alias_guid = alias_guid; 661 p_alias_guid->p_base_port = p_base_port; 662 } 663 return p_alias_guid; 664 } 665 666 void osm_alias_guid_delete(IN OUT osm_alias_guid_t ** pp_alias_guid) 667 { 668 free(*pp_alias_guid); 669 *pp_alias_guid = NULL; 670 } 671 672 void osm_physp_set_port_info(IN osm_physp_t * p_physp, 673 IN const ib_port_info_t * p_pi, 674 IN const struct osm_sm * p_sm) 675 { 676 CL_ASSERT(p_pi); 677 CL_ASSERT(osm_physp_is_valid(p_physp)); 678 679 if (ib_port_info_get_port_state(p_pi) == IB_LINK_DOWN) { 680 /* If PortState is down, only copy PortState */ 681 /* and PortPhysicalState per C14-24-2.1 */ 682 ib_port_info_set_port_state(&p_physp->port_info, IB_LINK_DOWN); 683 ib_port_info_set_port_phys_state 684 (ib_port_info_get_port_phys_state(p_pi), 685 &p_physp->port_info); 686 } else { 687 p_physp->port_info = *p_pi; 688 689 /* The MKey in p_pi can only be considered valid if it's 690 * for a HCA/router or switch port 0, and it's either 691 * non-zero or the MKeyProtect bits are also zero. 692 */ 693 if ((osm_node_get_type(p_physp->p_node) != 694 IB_NODE_TYPE_SWITCH || p_physp->port_num == 0) && 695 (p_pi->m_key != 0 || ib_port_info_get_mpb(p_pi) == 0)) 696 osm_db_guid2mkey_set(p_sm->p_subn->p_g2m, 697 cl_ntoh64(p_physp->port_guid), 698 cl_ntoh64(p_pi->m_key)); 699 } 700 } 701