1/* 2 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2002-2005 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#ifndef _OSM_PKEY_H_ 37#define _OSM_PKEY_H_ 38 39#include <iba/ib_types.h> 40#include <complib/cl_dispatcher.h> 41#include <complib/cl_map.h> 42#include <opensm/osm_base.h> 43#include <opensm/osm_log.h> 44#include <opensm/osm_msgdef.h> 45 46#ifdef __cplusplus 47# define BEGIN_C_DECLS extern "C" { 48# define END_C_DECLS } 49#else /* !__cplusplus */ 50# define BEGIN_C_DECLS 51# define END_C_DECLS 52#endif /* __cplusplus */ 53 54BEGIN_C_DECLS 55/* 56 Forward references. 57*/ 58struct osm_physp; 59struct osm_port; 60struct osm_subn; 61struct osm_node; 62struct osm_physp; 63 64/* 65 * Abstract: 66 * Declaration of pkey manipulation functions. 67 */ 68 69/****s* OpenSM: osm_pkey_tbl_t 70* NAME 71* osm_pkey_tbl_t 72* 73* DESCRIPTION 74* This object represents a pkey table. The need for a special object 75* is required to optimize search performance of a PKey in the IB standard 76* non sorted table. 77* 78* The osm_pkey_tbl_t object should be treated as opaque and should 79* be manipulated only through the provided functions. 80* 81* SYNOPSIS 82*/ 83typedef struct osm_pkeybl { 84 cl_ptr_vector_t blocks; 85 cl_ptr_vector_t new_blocks; 86 cl_map_t keys; 87 cl_qlist_t pending; 88 uint16_t used_blocks; 89 uint16_t max_blocks; 90} osm_pkey_tbl_t; 91/* 92* FIELDS 93* blocks 94* The IBA defined blocks of pkey values, updated from the subnet 95* 96* new_blocks 97* The blocks of pkey values, will be used for updates by SM 98* 99* keys 100* A set holding all keys 101* 102* pending 103* A list of osm_pending_pkey structs that is temporarily set by 104* the pkey mgr and used during pkey mgr algorithm only 105* 106* used_blocks 107* Tracks the number of blocks having non-zero pkeys 108* 109* max_blocks 110* The maximal number of blocks this partition table might hold 111* this value is based on node_info (for port 0 or CA) or 112* switch_info updated on receiving the node_info or switch_info 113* GetResp 114* 115* NOTES 116* 'blocks' vector should be used to store pkey values obtained from 117* the port and SM pkey manager should not change it directly, for this 118* purpose 'new_blocks' should be used. 119* 120* The only pkey values stored in 'blocks' vector will be mapped with 121* 'keys' map 122* 123*********/ 124 125/****s* OpenSM: osm_pending_pkey_t 126* NAME 127* osm_pending_pkey_t 128* 129* DESCRIPTION 130* This objects stores temporary information on pkeys, their target block, 131* and index during the pkey manager operation 132* 133* SYNOPSIS 134*/ 135typedef struct osm_pending_pkey { 136 cl_list_item_t list_item; 137 uint16_t pkey; 138 uint16_t block; 139 uint8_t index; 140 boolean_t is_new; 141} osm_pending_pkey_t; 142/* 143* FIELDS 144* pkey 145* The actual P_Key 146* 147* block 148* The block index based on the previous table extracted from the 149* device 150* 151* index 152* The index of the pkey within the block 153* 154* is_new 155* TRUE for new P_Keys such that the block and index are invalid 156* in that case 157* 158*********/ 159 160/****f* OpenSM: osm_pkey_tbl_construct 161* NAME 162* osm_pkey_tbl_construct 163* 164* DESCRIPTION 165* Constructs the PKey table object 166* 167* SYNOPSIS 168*/ 169void osm_pkey_tbl_construct(IN osm_pkey_tbl_t * p_pkey_tbl); 170/* 171* p_pkey_tbl 172* [in] Pointer to osm_pkey_tbl_t object. 173* 174* NOTES 175* 176*********/ 177 178/****f* OpenSM: osm_pkey_tbl_init 179* NAME 180* osm_pkey_tbl_init 181* 182* DESCRIPTION 183* Inits the PKey table object 184* 185* SYNOPSIS 186*/ 187ib_api_status_t osm_pkey_tbl_init(IN osm_pkey_tbl_t * p_pkey_tbl); 188/* 189* p_pkey_tbl 190* [in] Pointer to osm_pkey_tbl_t object. 191* 192* NOTES 193* 194*********/ 195 196/****f* OpenSM: osm_pkey_tbl_destroy 197* NAME 198* osm_pkey_tbl_destroy 199* 200* DESCRIPTION 201* Destroys the PKey table object 202* 203* SYNOPSIS 204*/ 205void osm_pkey_tbl_destroy(IN osm_pkey_tbl_t * p_pkey_tbl); 206/* 207* p_pkey_tbl 208* [in] Pointer to osm_pkey_tbl_t object. 209* 210* NOTES 211* 212*********/ 213 214/****f* OpenSM: osm_pkey_get_num_blocks 215* NAME 216* osm_pkey_get_num_blocks 217* 218* DESCRIPTION 219* Obtain the number of blocks in IB PKey table 220* 221* SYNOPSIS 222*/ 223static inline uint16_t 224osm_pkey_tbl_get_num_blocks(IN const osm_pkey_tbl_t * p_pkey_tbl) 225{ 226 return ((uint16_t) (cl_ptr_vector_get_size(&p_pkey_tbl->blocks))); 227} 228 229/* 230* p_pkey_tbl 231* [in] Pointer to osm_pkey_tbl_t object. 232* 233* RETURN VALUES 234* The IB pkey table of that pkey table element 235* 236* NOTES 237* 238*********/ 239 240/****f* OpenSM: osm_pkey_tbl_block_get 241* NAME 242* osm_pkey_tbl_block_get 243* 244* DESCRIPTION 245* Obtain the pointer to the IB PKey table block stored in the object 246* 247* SYNOPSIS 248*/ 249static inline ib_pkey_table_t *osm_pkey_tbl_block_get(const osm_pkey_tbl_t * 250 p_pkey_tbl, 251 uint16_t block) 252{ 253 return ((block < cl_ptr_vector_get_size(&p_pkey_tbl->blocks)) ? 254 cl_ptr_vector_get(&p_pkey_tbl->blocks, block) : NULL); 255}; 256 257/* 258* p_pkey_tbl 259* [in] Pointer to osm_pkey_tbl_t object. 260* 261* block 262* [in] The lock number to get 263* 264* RETURN VALUES 265* The IB pkey table of that pkey table element 266* 267* NOTES 268* 269*********/ 270 271/****f* OpenSM: osm_pkey_tbl_new_block_get 272* NAME 273* osm_pkey_tbl_new_block_get 274* 275* DESCRIPTION 276* The same as above but for new block 277* 278* SYNOPSIS 279*/ 280static inline ib_pkey_table_t *osm_pkey_tbl_new_block_get(const osm_pkey_tbl_t * 281 p_pkey_tbl, 282 uint16_t block) 283{ 284 return (block < cl_ptr_vector_get_size(&p_pkey_tbl->new_blocks)) ? 285 cl_ptr_vector_get(&p_pkey_tbl->new_blocks, block) : NULL; 286}; 287 288/****f* OpenSM: osm_pkey_tbl_set_new_entry 289* NAME 290* osm_pkey_tbl_set_new_entry 291* 292* DESCRIPTION 293* Stores the given pkey in the "new" blocks array and update 294* the "map" to show that on the "old" blocks 295* 296* SYNOPSIS 297*/ 298ib_api_status_t 299osm_pkey_tbl_set_new_entry(IN osm_pkey_tbl_t * p_pkey_tbl, 300 IN uint16_t block_idx, 301 IN uint8_t pkey_idx, IN uint16_t pkey); 302/* 303* p_pkey_tbl 304* [in] Pointer to the PKey table 305* 306* block_idx 307* [in] The block index to use 308* 309* pkey_idx 310* [in] The index within the block 311* 312* pkey 313* [in] PKey to store 314* 315* RETURN VALUES 316* IB_SUCCESS if OK 317* IB_ERROR if failed 318* 319*********/ 320 321/****f* OpenSM: osm_pkey_find_next_free_entry 322* NAME 323* osm_pkey_find_next_free_entry 324* 325* DESCRIPTION 326* Find the next free entry in the PKey table starting at the given 327* index and block number. The user should increment pkey_idx before 328* next call 329* Inspect the "new" blocks array for empty space. 330* 331* SYNOPSIS 332*/ 333boolean_t 334osm_pkey_find_next_free_entry(IN osm_pkey_tbl_t * p_pkey_tbl, 335 OUT uint16_t * p_block_idx, 336 OUT uint8_t * p_pkey_idx); 337/* 338* p_pkey_tbl 339* [in] Pointer to the PKey table 340* 341* p_block_idx 342* [out] The block index to use 343* 344* p_pkey_idx 345* [out] The index within the block to use 346* 347* RETURN VALUES 348* TRUE if found 349* FALSE if did not find 350* 351*********/ 352 353/****f* OpenSM: osm_pkey_tbl_init_new_blocks 354* NAME 355* osm_pkey_tbl_init_new_blocks 356* 357* DESCRIPTION 358* Initializes new_blocks vector content (allocate and clear) 359* 360* SYNOPSIS 361*/ 362void osm_pkey_tbl_init_new_blocks(const osm_pkey_tbl_t * p_pkey_tbl); 363/* 364* p_pkey_tbl 365* [in] Pointer to osm_pkey_tbl_t object. 366* 367* NOTES 368* 369*********/ 370 371/****f* OpenSM: osm_pkey_tbl_get_block_and_idx 372* NAME 373* osm_pkey_tbl_get_block_and_idx 374* 375* DESCRIPTION 376* Set the block index and pkey index the given 377* pkey is found in. Return IB_NOT_FOUND if could 378* not find it, IB_SUCCESS if OK 379* 380* SYNOPSIS 381*/ 382ib_api_status_t 383osm_pkey_tbl_get_block_and_idx(IN osm_pkey_tbl_t * p_pkey_tbl, 384 IN uint16_t * p_pkey, 385 OUT uint16_t * block_idx, 386 OUT uint8_t * pkey_index); 387/* 388* p_pkey_tbl 389* [in] Pointer to osm_pkey_tbl_t object. 390* 391* p_pkey 392* [in] Pointer to the P_Key entry searched 393* 394* p_block_idx 395* [out] Pointer to the block index to be updated 396* 397* p_pkey_idx 398* [out] Pointer to the pkey index (in the block) to be updated 399* 400* NOTES 401* 402*********/ 403 404/****f* OpenSM: osm_pkey_tbl_set 405* NAME 406* osm_pkey_tbl_set 407* 408* DESCRIPTION 409* Set the PKey table block provided in the PKey object. 410* 411* SYNOPSIS 412*/ 413ib_api_status_t 414osm_pkey_tbl_set(IN osm_pkey_tbl_t * p_pkey_tbl, 415 IN uint16_t block, IN ib_pkey_table_t * p_tbl); 416/* 417* p_pkey_tbl 418* [in] Pointer to osm_pkey_tbl_t object. 419* 420* block 421* [in] The block number to set 422* 423* p_tbl 424* [in] The IB PKey block to copy to the object 425* 426* RETURN VALUES 427* IB_SUCCESS or IB_ERROR 428* 429* NOTES 430* 431*********/ 432 433/****f* OpenSM: osm_physp_share_this_pkey 434* NAME 435* osm_physp_share_this_pkey 436* 437* DESCRIPTION 438* Checks if the given physical ports share the specified pkey. 439* 440* SYNOPSIS 441*/ 442boolean_t osm_physp_share_this_pkey(IN const struct osm_physp *const p_physp1, 443 IN const struct osm_physp *const p_physp2, 444 IN const ib_net16_t pkey); 445/* 446* PARAMETERS 447* 448* p_physp1 449* [in] Pointer to an osm_physp_t object. 450* 451* p_physp2 452* [in] Pointer to an osm_physp_t object. 453* 454* pkey 455* [in] value of P_Key to check. 456* 457* RETURN VALUES 458* Returns TRUE if the two ports are matching. 459* FALSE otherwise. 460* 461* NOTES 462* 463*********/ 464 465/****f* OpenSM: osm_physp_find_common_pkey 466* NAME 467* osm_physp_find_common_pkey 468* 469* DESCRIPTION 470* Returns first matching P_Key values for specified physical ports. 471* 472* SYNOPSIS 473*/ 474ib_net16_t osm_physp_find_common_pkey(IN const struct osm_physp *const 475 p_physp1, 476 IN const struct osm_physp *const 477 p_physp2); 478/* 479* PARAMETERS 480* 481* p_physp1 482* [in] Pointer to an osm_physp_t object. 483* 484* p_physp2 485* [in] Pointer to an osm_physp_t object. 486* 487* RETURN VALUES 488* Returns value of first shared P_Key or INVALID P_Key (0x0) if not 489* found. 490* 491* NOTES 492* 493*********/ 494 495/****f* OpenSM: osm_physp_share_pkey 496* NAME 497* osm_physp_share_pkey 498* 499* DESCRIPTION 500* Checks if the given physical ports share a pkey. 501* The meaning P_Key matching: 502* 10.9.3 : 503* In the following, let M_P_Key(Message P_Key) be the P_Key in the incoming 504* packet and E_P_Key(Endnode P_Key) be the P_Key it is being compared against 505* in the packet's destination endnode. 506* 507* If: 508* * neither M_P_Key nor E_P_Key are the invalid P_Key 509* * and the low-order 15 bits of the M_P_Key match the low order 15 510* bits of the E_P_Key 511* * and the high order bit(membership type) of both the M_P_Key and 512* E_P_Key are not both 0 (i.e., both are not Limited members of 513* the partition) 514* 515* then the P_Keys are said to match. 516* 517* SYNOPSIS 518*/ 519boolean_t osm_physp_share_pkey(IN osm_log_t * p_log, 520 IN const struct osm_physp *const p_physp_1, 521 IN const struct osm_physp *const p_physp_2); 522 523/* 524* PARAMETERS 525* p_log 526* [in] Pointer to a log object. 527* 528* p_physp_1 529* [in] Pointer to an osm_physp_t object. 530* 531* p_physp_2 532* [in] Pointer to an osm_physp_t object. 533* 534* RETURN VALUES 535* Returns TRUE if the 2 physical ports are matching. 536* FALSE otherwise. 537* 538* NOTES 539* 540*********/ 541 542/****f* OpenSM: osm_port_share_pkey 543* NAME 544* osm_port_share_pkey 545* 546* DESCRIPTION 547* Checks if the given ports (on their default physical port) share a pkey. 548* The meaning P_Key matching: 549* 10.9.3 : 550* In the following, let M_P_Key(Message P_Key) be the P_Key in the incoming 551* packet and E_P_Key(Endnode P_Key) be the P_Key it is being compared against 552* in the packet's destination endnode. 553* 554* If: 555* * neither M_P_Key nor E_P_Key are the invalid P_Key 556* * and the low-order 15 bits of the M_P_Key match the low order 15 557* bits of the E_P_Key 558* * and the high order bit(membership type) of both the M_P_Key and 559* E_P_Key are not both 0 (i.e., both are not Limited members of 560* the partition) 561* 562* then the P_Keys are said to match. 563* 564* SYNOPSIS 565*/ 566boolean_t osm_port_share_pkey(IN osm_log_t * p_log, 567 IN const struct osm_port *const p_port_1, 568 IN const struct osm_port *const p_port_2); 569 570/* 571* PARAMETERS 572* p_log 573* [in] Pointer to a log object. 574* 575* p_port_1 576* [in] Pointer to an osm_port_t object. 577* 578* p_port_2 579* [in] Pointer to an osm_port_t object. 580* 581* RETURN VALUES 582* Returns TRUE if the 2 ports are matching. 583* FALSE otherwise. 584* 585* NOTES 586* 587*********/ 588 589/****f* OpenSM: osm_physp_has_pkey 590* NAME 591* osm_physp_has_pkey 592* 593* DESCRIPTION 594* Checks if the given lids and port_numbers share a pkey. 595* The meaning P_Key matching: 596* 10.9.3 : 597* In the following, let M_P_Key(Message P_Key) be the P_Key in the incoming 598* packet and E_P_Key(Endnode P_Key) be the P_Key it is being compared against 599* in the packet's destination endnode. 600* 601* If: 602* * neither M_P_Key nor E_P_Key are the invalid P_Key 603* * and the low-order 15 bits of the M_P_Key match the low order 15 604* bits of the E_P_Key 605* * and the high order bit(membership type) of both the M_P_Key and 606* E_P_Key are not both 0 (i.e., both are not Limited members of 607* the partition) 608* 609* then the P_Keys are said to match. 610* 611* SYNOPSIS 612*/ 613boolean_t osm_physp_has_pkey(IN osm_log_t * p_log, 614 IN const ib_net16_t pkey, 615 IN const struct osm_physp *const p_physp); 616 617/* 618* PARAMETERS 619* p_log 620* [in] Pointer to a log object. 621* 622* pkey 623* [in] pkey number to look for. 624* 625* p_physp 626* [in] Pointer to osm_physp_t object. 627* 628* RETURN VALUES 629* Returns TRUE if the p_physp has the pkey given. False otherwise. 630* 631* NOTES 632* 633*********/ 634 635END_C_DECLS 636#endif /* _OSM_PKEY_H_ */ 637