1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved. 3219820Sjeff * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved. 4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5219820Sjeff * 6219820Sjeff * This software is available to you under a choice of one of two 7219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 8219820Sjeff * General Public License (GPL) Version 2, available from the file 9219820Sjeff * COPYING in the main directory of this source tree, or the 10219820Sjeff * OpenIB.org BSD license below: 11219820Sjeff * 12219820Sjeff * Redistribution and use in source and binary forms, with or 13219820Sjeff * without modification, are permitted provided that the following 14219820Sjeff * conditions are met: 15219820Sjeff * 16219820Sjeff * - Redistributions of source code must retain the above 17219820Sjeff * copyright notice, this list of conditions and the following 18219820Sjeff * disclaimer. 19219820Sjeff * 20219820Sjeff * - Redistributions in binary form must reproduce the above 21219820Sjeff * copyright notice, this list of conditions and the following 22219820Sjeff * disclaimer in the documentation and/or other materials 23219820Sjeff * provided with the distribution. 24219820Sjeff * 25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32219820Sjeff * SOFTWARE. 33219820Sjeff * 34219820Sjeff */ 35219820Sjeff 36219820Sjeff/* 37219820Sjeff * Abstract: 38219820Sjeff * Implementation of opensm pkey manipulation functions. 39219820Sjeff */ 40219820Sjeff 41219820Sjeff#if HAVE_CONFIG_H 42219820Sjeff# include <config.h> 43219820Sjeff#endif /* HAVE_CONFIG_H */ 44219820Sjeff 45219820Sjeff#include <stdlib.h> 46219820Sjeff#include <stdio.h> 47219820Sjeff#include <string.h> 48219820Sjeff#include <complib/cl_debug.h> 49219820Sjeff#include <iba/ib_types.h> 50219820Sjeff#include <opensm/osm_pkey.h> 51219820Sjeff#include <opensm/osm_log.h> 52219820Sjeff#include <opensm/osm_port.h> 53219820Sjeff#include <opensm/osm_node.h> 54219820Sjeff#include <opensm/osm_switch.h> 55219820Sjeff#include <opensm/osm_helper.h> 56219820Sjeff 57219820Sjeff/********************************************************************** 58219820Sjeff **********************************************************************/ 59219820Sjeffvoid osm_pkey_tbl_construct(IN osm_pkey_tbl_t * p_pkey_tbl) 60219820Sjeff{ 61219820Sjeff cl_ptr_vector_construct(&p_pkey_tbl->blocks); 62219820Sjeff cl_ptr_vector_construct(&p_pkey_tbl->new_blocks); 63219820Sjeff cl_map_construct(&p_pkey_tbl->keys); 64219820Sjeff} 65219820Sjeff 66219820Sjeff/********************************************************************** 67219820Sjeff **********************************************************************/ 68219820Sjeffvoid osm_pkey_tbl_destroy(IN osm_pkey_tbl_t * p_pkey_tbl) 69219820Sjeff{ 70219820Sjeff ib_pkey_table_t *p_block; 71219820Sjeff uint16_t num_blocks, i; 72219820Sjeff 73219820Sjeff num_blocks = (uint16_t) (cl_ptr_vector_get_size(&p_pkey_tbl->blocks)); 74219820Sjeff for (i = 0; i < num_blocks; i++) 75219820Sjeff if ((p_block = cl_ptr_vector_get(&p_pkey_tbl->blocks, i))) 76219820Sjeff free(p_block); 77219820Sjeff cl_ptr_vector_destroy(&p_pkey_tbl->blocks); 78219820Sjeff 79219820Sjeff num_blocks = 80219820Sjeff (uint16_t) (cl_ptr_vector_get_size(&p_pkey_tbl->new_blocks)); 81219820Sjeff for (i = 0; i < num_blocks; i++) 82219820Sjeff if ((p_block = cl_ptr_vector_get(&p_pkey_tbl->new_blocks, i))) 83219820Sjeff free(p_block); 84219820Sjeff cl_ptr_vector_destroy(&p_pkey_tbl->new_blocks); 85219820Sjeff 86219820Sjeff cl_map_remove_all(&p_pkey_tbl->keys); 87219820Sjeff cl_map_destroy(&p_pkey_tbl->keys); 88219820Sjeff} 89219820Sjeff 90219820Sjeff/********************************************************************** 91219820Sjeff **********************************************************************/ 92219820Sjeffib_api_status_t osm_pkey_tbl_init(IN osm_pkey_tbl_t * p_pkey_tbl) 93219820Sjeff{ 94219820Sjeff cl_ptr_vector_init(&p_pkey_tbl->blocks, 0, 1); 95219820Sjeff cl_ptr_vector_init(&p_pkey_tbl->new_blocks, 0, 1); 96219820Sjeff cl_map_init(&p_pkey_tbl->keys, 1); 97219820Sjeff cl_qlist_init(&p_pkey_tbl->pending); 98219820Sjeff p_pkey_tbl->used_blocks = 0; 99219820Sjeff p_pkey_tbl->max_blocks = 0; 100219820Sjeff return (IB_SUCCESS); 101219820Sjeff} 102219820Sjeff 103219820Sjeff/********************************************************************** 104219820Sjeff **********************************************************************/ 105219820Sjeffvoid osm_pkey_tbl_init_new_blocks(IN const osm_pkey_tbl_t * p_pkey_tbl) 106219820Sjeff{ 107219820Sjeff ib_pkey_table_t *p_block; 108219820Sjeff size_t b, num_blocks = cl_ptr_vector_get_size(&p_pkey_tbl->new_blocks); 109219820Sjeff 110219820Sjeff for (b = 0; b < num_blocks; b++) 111219820Sjeff if ((p_block = cl_ptr_vector_get(&p_pkey_tbl->new_blocks, b))) 112219820Sjeff memset(p_block, 0, sizeof(*p_block)); 113219820Sjeff} 114219820Sjeff 115219820Sjeff/********************************************************************** 116219820Sjeff **********************************************************************/ 117219820Sjeffvoid osm_pkey_tbl_cleanup_pending(IN osm_pkey_tbl_t * p_pkey_tbl) 118219820Sjeff{ 119219820Sjeff cl_list_item_t *p_item; 120219820Sjeff 121219820Sjeff p_item = cl_qlist_remove_head(&p_pkey_tbl->pending); 122219820Sjeff while (p_item != cl_qlist_end(&p_pkey_tbl->pending)) { 123219820Sjeff free((osm_pending_pkey_t *) p_item); 124219820Sjeff } 125219820Sjeff} 126219820Sjeff 127219820Sjeff/********************************************************************** 128219820Sjeff **********************************************************************/ 129219820Sjeffib_api_status_t 130219820Sjeffosm_pkey_tbl_set(IN osm_pkey_tbl_t * p_pkey_tbl, 131219820Sjeff IN uint16_t block, IN ib_pkey_table_t * p_tbl) 132219820Sjeff{ 133219820Sjeff uint16_t b, i; 134219820Sjeff ib_pkey_table_t *p_pkey_block; 135219820Sjeff uint16_t *p_prev_pkey; 136219820Sjeff ib_net16_t pkey; 137219820Sjeff 138219820Sjeff /* make sure the block is allocated */ 139219820Sjeff if (cl_ptr_vector_get_size(&p_pkey_tbl->blocks) > block) 140219820Sjeff p_pkey_block = 141219820Sjeff (ib_pkey_table_t *) cl_ptr_vector_get(&p_pkey_tbl->blocks, 142219820Sjeff block); 143219820Sjeff else 144219820Sjeff p_pkey_block = NULL; 145219820Sjeff 146219820Sjeff if (!p_pkey_block) { 147219820Sjeff p_pkey_block = 148219820Sjeff (ib_pkey_table_t *) malloc(sizeof(ib_pkey_table_t)); 149219820Sjeff if (!p_pkey_block) 150219820Sjeff return (IB_ERROR); 151219820Sjeff memset(p_pkey_block, 0, sizeof(ib_pkey_table_t)); 152219820Sjeff cl_ptr_vector_set(&p_pkey_tbl->blocks, block, p_pkey_block); 153219820Sjeff } 154219820Sjeff 155219820Sjeff /* sets the block values */ 156219820Sjeff memcpy(p_pkey_block, p_tbl, sizeof(ib_pkey_table_t)); 157219820Sjeff 158219820Sjeff /* 159219820Sjeff NOTE: as the spec does not require uniqueness of PKeys in 160219820Sjeff tables there is no other way but to refresh the entire keys map. 161219820Sjeff 162219820Sjeff Moreover, if the same key exists but with full membership it should 163219820Sjeff have precedence on the key with limited membership ! 164219820Sjeff */ 165219820Sjeff cl_map_remove_all(&p_pkey_tbl->keys); 166219820Sjeff 167219820Sjeff for (b = 0; b < cl_ptr_vector_get_size(&p_pkey_tbl->blocks); b++) { 168219820Sjeff 169219820Sjeff p_pkey_block = cl_ptr_vector_get(&p_pkey_tbl->blocks, b); 170219820Sjeff if (!p_pkey_block) 171219820Sjeff continue; 172219820Sjeff 173219820Sjeff for (i = 0; i < IB_NUM_PKEY_ELEMENTS_IN_BLOCK; i++) { 174219820Sjeff pkey = p_pkey_block->pkey_entry[i]; 175219820Sjeff if (ib_pkey_is_invalid(pkey)) 176219820Sjeff continue; 177219820Sjeff 178219820Sjeff /* 179219820Sjeff ignore the PKey Full Member bit in the key but store 180219820Sjeff the pointer to the table element as the map value 181219820Sjeff */ 182219820Sjeff p_prev_pkey = 183219820Sjeff cl_map_get(&p_pkey_tbl->keys, 184219820Sjeff ib_pkey_get_base(pkey)); 185219820Sjeff 186219820Sjeff /* we only insert if no previous or it is not full member */ 187219820Sjeff if ((p_prev_pkey == NULL) || 188219820Sjeff (cl_ntoh16(*p_prev_pkey) < cl_ntoh16(pkey))) 189219820Sjeff cl_map_insert(&p_pkey_tbl->keys, 190219820Sjeff ib_pkey_get_base(pkey), 191219820Sjeff &(p_pkey_block->pkey_entry[i]) 192219820Sjeff ); 193219820Sjeff } 194219820Sjeff } 195219820Sjeff return (IB_SUCCESS); 196219820Sjeff} 197219820Sjeff 198219820Sjeff/********************************************************************** 199219820Sjeff **********************************************************************/ 200219820Sjeff/* 201219820Sjeff Store the given pkey in the "new" blocks array. 202219820Sjeff Also, make sure the regular block exists. 203219820Sjeff*/ 204219820Sjeffib_api_status_t 205219820Sjeffosm_pkey_tbl_set_new_entry(IN osm_pkey_tbl_t * p_pkey_tbl, 206219820Sjeff IN uint16_t block_idx, 207219820Sjeff IN uint8_t pkey_idx, IN uint16_t pkey) 208219820Sjeff{ 209219820Sjeff ib_pkey_table_t *p_block; 210219820Sjeff 211219820Sjeff if (!(p_block = osm_pkey_tbl_new_block_get(p_pkey_tbl, block_idx))) { 212219820Sjeff p_block = (ib_pkey_table_t *) malloc(sizeof(ib_pkey_table_t)); 213219820Sjeff if (!p_block) 214219820Sjeff return (IB_ERROR); 215219820Sjeff memset(p_block, 0, sizeof(ib_pkey_table_t)); 216219820Sjeff cl_ptr_vector_set(&p_pkey_tbl->new_blocks, block_idx, p_block); 217219820Sjeff } 218219820Sjeff 219219820Sjeff p_block->pkey_entry[pkey_idx] = pkey; 220219820Sjeff if (p_pkey_tbl->used_blocks <= block_idx) 221219820Sjeff p_pkey_tbl->used_blocks = block_idx + 1; 222219820Sjeff 223219820Sjeff return (IB_SUCCESS); 224219820Sjeff} 225219820Sjeff 226219820Sjeff/********************************************************************** 227219820Sjeff **********************************************************************/ 228219820Sjeffboolean_t 229219820Sjeffosm_pkey_find_next_free_entry(IN osm_pkey_tbl_t * p_pkey_tbl, 230219820Sjeff OUT uint16_t * p_block_idx, 231219820Sjeff OUT uint8_t * p_pkey_idx) 232219820Sjeff{ 233219820Sjeff ib_pkey_table_t *p_new_block; 234219820Sjeff 235219820Sjeff CL_ASSERT(p_block_idx); 236219820Sjeff CL_ASSERT(p_pkey_idx); 237219820Sjeff 238219820Sjeff while (*p_block_idx < p_pkey_tbl->max_blocks) { 239219820Sjeff if (*p_pkey_idx > IB_NUM_PKEY_ELEMENTS_IN_BLOCK - 1) { 240219820Sjeff *p_pkey_idx = 0; 241219820Sjeff (*p_block_idx)++; 242219820Sjeff if (*p_block_idx >= p_pkey_tbl->max_blocks) 243219820Sjeff return FALSE; 244219820Sjeff } 245219820Sjeff 246219820Sjeff p_new_block = 247219820Sjeff osm_pkey_tbl_new_block_get(p_pkey_tbl, *p_block_idx); 248219820Sjeff 249219820Sjeff if (!p_new_block || 250219820Sjeff ib_pkey_is_invalid(p_new_block->pkey_entry[*p_pkey_idx])) 251219820Sjeff return TRUE; 252219820Sjeff else 253219820Sjeff (*p_pkey_idx)++; 254219820Sjeff } 255219820Sjeff return FALSE; 256219820Sjeff} 257219820Sjeff 258219820Sjeff/********************************************************************** 259219820Sjeff **********************************************************************/ 260219820Sjeffib_api_status_t 261219820Sjeffosm_pkey_tbl_get_block_and_idx(IN osm_pkey_tbl_t * p_pkey_tbl, 262219820Sjeff IN uint16_t * p_pkey, 263219820Sjeff OUT uint16_t * p_block_idx, 264219820Sjeff OUT uint8_t * p_pkey_idx) 265219820Sjeff{ 266219820Sjeff uint16_t num_of_blocks; 267219820Sjeff uint16_t block_index; 268219820Sjeff ib_pkey_table_t *block; 269219820Sjeff 270219820Sjeff CL_ASSERT(p_block_idx != NULL); 271219820Sjeff CL_ASSERT(p_pkey_idx != NULL); 272219820Sjeff 273219820Sjeff num_of_blocks = (uint16_t) cl_ptr_vector_get_size(&p_pkey_tbl->blocks); 274219820Sjeff for (block_index = 0; block_index < num_of_blocks; block_index++) { 275219820Sjeff block = osm_pkey_tbl_block_get(p_pkey_tbl, block_index); 276219820Sjeff if ((block->pkey_entry <= p_pkey) && 277219820Sjeff (p_pkey < 278219820Sjeff block->pkey_entry + IB_NUM_PKEY_ELEMENTS_IN_BLOCK)) { 279219820Sjeff *p_block_idx = block_index; 280219820Sjeff *p_pkey_idx = (uint8_t) (p_pkey - block->pkey_entry); 281219820Sjeff return (IB_SUCCESS); 282219820Sjeff } 283219820Sjeff } 284219820Sjeff return (IB_NOT_FOUND); 285219820Sjeff} 286219820Sjeff 287219820Sjeff/********************************************************************** 288219820Sjeff **********************************************************************/ 289219820Sjeffstatic boolean_t 290219820Sjeff__osm_match_pkey(IN const ib_net16_t * pkey1, IN const ib_net16_t * pkey2) 291219820Sjeff{ 292219820Sjeff 293219820Sjeff /* if both pkeys are not full member - this is not a match */ 294219820Sjeff if (!(ib_pkey_is_full_member(*pkey1) || ib_pkey_is_full_member(*pkey2))) 295219820Sjeff return (FALSE); 296219820Sjeff 297219820Sjeff /* compare if the bases are the same. if they are - then 298219820Sjeff this is a match */ 299219820Sjeff if (ib_pkey_get_base(*pkey1) != ib_pkey_get_base(*pkey2)) 300219820Sjeff return (FALSE); 301219820Sjeff 302219820Sjeff return (TRUE); 303219820Sjeff} 304219820Sjeff 305219820Sjeff/********************************************************************** 306219820Sjeff **********************************************************************/ 307219820Sjeffboolean_t 308219820Sjeffosm_physp_share_this_pkey(IN const osm_physp_t * const p_physp1, 309219820Sjeff IN const osm_physp_t * const p_physp2, 310219820Sjeff IN const ib_net16_t pkey) 311219820Sjeff{ 312219820Sjeff ib_net16_t *pkey1, *pkey2; 313219820Sjeff 314219820Sjeff pkey1 = cl_map_get(&(osm_physp_get_pkey_tbl(p_physp1))->keys, 315219820Sjeff ib_pkey_get_base(pkey)); 316219820Sjeff pkey2 = cl_map_get(&(osm_physp_get_pkey_tbl(p_physp2))->keys, 317219820Sjeff ib_pkey_get_base(pkey)); 318219820Sjeff return (pkey1 && pkey2 && __osm_match_pkey(pkey1, pkey2)); 319219820Sjeff} 320219820Sjeff 321219820Sjeff/********************************************************************** 322219820Sjeff **********************************************************************/ 323219820Sjeffib_net16_t 324219820Sjeffosm_physp_find_common_pkey(IN const osm_physp_t * const p_physp1, 325219820Sjeff IN const osm_physp_t * const p_physp2) 326219820Sjeff{ 327219820Sjeff ib_net16_t *pkey1, *pkey2; 328219820Sjeff uint64_t pkey1_base, pkey2_base; 329219820Sjeff const osm_pkey_tbl_t *pkey_tbl1, *pkey_tbl2; 330219820Sjeff cl_map_iterator_t map_iter1, map_iter2; 331219820Sjeff 332219820Sjeff pkey_tbl1 = osm_physp_get_pkey_tbl(p_physp1); 333219820Sjeff pkey_tbl2 = osm_physp_get_pkey_tbl(p_physp2); 334219820Sjeff 335219820Sjeff map_iter1 = cl_map_head(&pkey_tbl1->keys); 336219820Sjeff map_iter2 = cl_map_head(&pkey_tbl2->keys); 337219820Sjeff 338219820Sjeff /* we rely on the fact the map are sorted by pkey */ 339219820Sjeff while ((map_iter1 != cl_map_end(&pkey_tbl1->keys)) && 340219820Sjeff (map_iter2 != cl_map_end(&pkey_tbl2->keys))) { 341219820Sjeff pkey1 = (ib_net16_t *) cl_map_obj(map_iter1); 342219820Sjeff pkey2 = (ib_net16_t *) cl_map_obj(map_iter2); 343219820Sjeff 344219820Sjeff if (__osm_match_pkey(pkey1, pkey2)) 345219820Sjeff return *pkey1; 346219820Sjeff 347219820Sjeff /* advance the lower value if they are not equal */ 348219820Sjeff pkey1_base = cl_map_key(map_iter1); 349219820Sjeff pkey2_base = cl_map_key(map_iter2); 350219820Sjeff if (pkey2_base == pkey1_base) { 351219820Sjeff map_iter1 = cl_map_next(map_iter1); 352219820Sjeff map_iter2 = cl_map_next(map_iter2); 353219820Sjeff } else if (pkey2_base < pkey1_base) 354219820Sjeff map_iter2 = cl_map_next(map_iter2); 355219820Sjeff else 356219820Sjeff map_iter1 = cl_map_next(map_iter1); 357219820Sjeff } 358219820Sjeff 359219820Sjeff return 0; 360219820Sjeff} 361219820Sjeff 362219820Sjeff/********************************************************************** 363219820Sjeff **********************************************************************/ 364219820Sjeffboolean_t 365219820Sjeffosm_physp_share_pkey(IN osm_log_t * p_log, 366219820Sjeff IN const osm_physp_t * const p_physp_1, 367219820Sjeff IN const osm_physp_t * const p_physp_2) 368219820Sjeff{ 369219820Sjeff const osm_pkey_tbl_t *pkey_tbl1, *pkey_tbl2; 370219820Sjeff 371219820Sjeff if (p_physp_1 == p_physp_2) 372219820Sjeff return TRUE; 373219820Sjeff 374219820Sjeff pkey_tbl1 = osm_physp_get_pkey_tbl(p_physp_1); 375219820Sjeff pkey_tbl2 = osm_physp_get_pkey_tbl(p_physp_2); 376219820Sjeff 377219820Sjeff /* 378219820Sjeff The spec: 10.9.2 does not require each phys port to have PKey Table. 379219820Sjeff So actually if it does not, we need to use the default port instead. 380219820Sjeff 381219820Sjeff HACK: meanwhile we will ignore the check 382219820Sjeff */ 383219820Sjeff if (cl_is_map_empty(&pkey_tbl1->keys) 384219820Sjeff || cl_is_map_empty(&pkey_tbl2->keys)) 385219820Sjeff return TRUE; 386219820Sjeff 387219820Sjeff return 388219820Sjeff !ib_pkey_is_invalid(osm_physp_find_common_pkey 389219820Sjeff (p_physp_1, p_physp_2)); 390219820Sjeff} 391219820Sjeff 392219820Sjeff/********************************************************************** 393219820Sjeff **********************************************************************/ 394219820Sjeffboolean_t 395219820Sjeffosm_port_share_pkey(IN osm_log_t * p_log, 396219820Sjeff IN const osm_port_t * const p_port_1, 397219820Sjeff IN const osm_port_t * const p_port_2) 398219820Sjeff{ 399219820Sjeff 400219820Sjeff osm_physp_t *p_physp1, *p_physp2; 401219820Sjeff boolean_t ret; 402219820Sjeff 403219820Sjeff OSM_LOG_ENTER(p_log); 404219820Sjeff 405219820Sjeff if (!p_port_1 || !p_port_2) { 406219820Sjeff ret = FALSE; 407219820Sjeff goto Exit; 408219820Sjeff } 409219820Sjeff 410219820Sjeff p_physp1 = p_port_1->p_physp; 411219820Sjeff p_physp2 = p_port_2->p_physp; 412219820Sjeff 413219820Sjeff if (!p_physp1 || !p_physp2) { 414219820Sjeff ret = FALSE; 415219820Sjeff goto Exit; 416219820Sjeff } 417219820Sjeff 418219820Sjeff ret = osm_physp_share_pkey(p_log, p_physp1, p_physp2); 419219820Sjeff 420219820SjeffExit: 421219820Sjeff OSM_LOG_EXIT(p_log); 422219820Sjeff return ret; 423219820Sjeff} 424219820Sjeff 425219820Sjeff/********************************************************************** 426219820Sjeff **********************************************************************/ 427219820Sjeffboolean_t 428219820Sjeffosm_physp_has_pkey(IN osm_log_t * p_log, 429219820Sjeff IN const ib_net16_t pkey, 430219820Sjeff IN const osm_physp_t * const p_physp) 431219820Sjeff{ 432219820Sjeff 433219820Sjeff ib_net16_t *p_pkey, pkey_base; 434219820Sjeff const osm_pkey_tbl_t *pkey_tbl; 435219820Sjeff boolean_t res = FALSE; 436219820Sjeff 437219820Sjeff OSM_LOG_ENTER(p_log); 438219820Sjeff 439219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, 440219820Sjeff "Search for PKey: 0x%04x\n", cl_ntoh16(pkey)); 441219820Sjeff 442219820Sjeff /* if the pkey given is an invalid pkey - return TRUE. */ 443219820Sjeff if (ib_pkey_is_invalid(pkey)) { 444219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, 445219820Sjeff "Given invalid PKey - we treat it loosely and allow it\n"); 446219820Sjeff res = TRUE; 447219820Sjeff goto Exit; 448219820Sjeff } 449219820Sjeff 450219820Sjeff pkey_base = ib_pkey_get_base(pkey); 451219820Sjeff 452219820Sjeff pkey_tbl = osm_physp_get_pkey_tbl(p_physp); 453219820Sjeff 454219820Sjeff p_pkey = cl_map_get(&pkey_tbl->keys, pkey_base); 455219820Sjeff if (p_pkey) { 456219820Sjeff res = TRUE; 457219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, 458219820Sjeff "PKey 0x%04x was found\n", cl_ntoh16(pkey)); 459219820Sjeff } else { 460219820Sjeff OSM_LOG(p_log, OSM_LOG_DEBUG, 461219820Sjeff "PKey 0x%04x was not found\n", cl_ntoh16(pkey)); 462219820Sjeff } 463219820Sjeff 464219820SjeffExit: 465219820Sjeff OSM_LOG_EXIT(p_log); 466219820Sjeff return res; 467219820Sjeff} 468