1/* 2 * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. 4 * Copyright (c) 2002-2012 Mellanox Technologies LTD. All rights reserved. 5 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 6 * 7 * This software is available to you under a choice of one of two 8 * licenses. You may choose to be licensed under the terms of the GNU 9 * General Public License (GPL) Version 2, available from the file 10 * COPYING in the main directory of this source tree, or the 11 * OpenIB.org BSD license below: 12 * 13 * Redistribution and use in source and binary forms, with or 14 * without modification, are permitted provided that the following 15 * conditions are met: 16 * 17 * - Redistributions of source code must retain the above 18 * copyright notice, this list of conditions and the following 19 * disclaimer. 20 * 21 * - Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials 24 * provided with the distribution. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 * SOFTWARE. 34 * 35 */ 36 37#ifndef _OSM_PKEY_H_ 38#define _OSM_PKEY_H_ 39 40#include <iba/ib_types.h> 41#include <complib/cl_dispatcher.h> 42#include <complib/cl_map.h> 43#include <opensm/osm_base.h> 44#include <opensm/osm_log.h> 45#include <opensm/osm_msgdef.h> 46 47#ifdef __cplusplus 48# define BEGIN_C_DECLS extern "C" { 49# define END_C_DECLS } 50#else /* !__cplusplus */ 51# define BEGIN_C_DECLS 52# define END_C_DECLS 53#endif /* __cplusplus */ 54 55BEGIN_C_DECLS 56/* 57 Forward references. 58*/ 59struct osm_physp; 60struct osm_port; 61struct osm_subn; 62struct osm_node; 63struct osm_physp; 64 65/* 66 * Abstract: 67 * Declaration of pkey manipulation functions. 68 */ 69 70/****s* OpenSM: osm_pkey_tbl_t 71* NAME 72* osm_pkey_tbl_t 73* 74* DESCRIPTION 75* This object represents a pkey table. The need for a special object 76* is required to optimize search performance of a PKey in the IB standard 77* non sorted table. 78* 79* The osm_pkey_tbl_t object should be treated as opaque and should 80* be manipulated only through the provided functions. 81* 82* SYNOPSIS 83*/ 84typedef struct osm_pkeybl { 85 cl_map_t accum_pkeys; 86 cl_ptr_vector_t blocks; 87 cl_ptr_vector_t new_blocks; 88 cl_map_t keys; 89 cl_qlist_t pending; 90 uint16_t last_pkey_idx; 91 uint16_t used_blocks; 92 uint16_t max_blocks; 93 uint16_t rcv_blocks_cnt; 94 uint16_t indx0_pkey; 95} osm_pkey_tbl_t; 96/* 97* FIELDS 98* accum_pkeys 99* Accumulated pkeys with pkey index. Used to 100* preserve pkey index. 101* 102* blocks 103* The IBA defined blocks of pkey values, updated from the subnet 104* 105* new_blocks 106* The blocks of pkey values, will be used for updates by SM 107* 108* keys 109* A set holding all keys 110* 111* pending 112* A list of osm_pending_pkey structs that is temporarily set by 113* the pkey mgr and used during pkey mgr algorithm only 114* 115* used_blocks 116* Tracks the number of blocks having non-zero pkeys 117* 118* max_blocks 119* The maximal number of blocks this partition table might hold 120* this value is based on node_info (for port 0 or CA) or 121* switch_info updated on receiving the node_info or switch_info 122* GetResp 123* 124* rcv_blocks_cnt 125* Counter for the received GetPKeyTable mads. 126* For every GetPKeyTable mad we send, increase the counter, 127* and for every GetRespPKeyTable we decrease the counter. 128* 129* indx0_pkey 130* stores the pkey to be inserted at block 0 index 0. 131* if this field is 0, the default pkey will be inserted. 132* 133* NOTES 134* 'blocks' vector should be used to store pkey values obtained from 135* the port and SM pkey manager should not change it directly, for this 136* purpose 'new_blocks' should be used. 137* 138* The only pkey values stored in 'blocks' vector will be mapped with 139* 'keys' map 140* 141*********/ 142 143/****s* OpenSM: osm_pending_pkey_t 144* NAME 145* osm_pending_pkey_t 146* 147* DESCRIPTION 148* This objects stores temporary information on pkeys, their target block, 149* and index during the pkey manager operation 150* 151* SYNOPSIS 152*/ 153typedef struct osm_pending_pkey { 154 cl_list_item_t list_item; 155 uint16_t pkey; 156 uint16_t block; 157 uint8_t index; 158 boolean_t is_new; 159} osm_pending_pkey_t; 160/* 161* FIELDS 162* pkey 163* The actual P_Key 164* 165* block 166* The block index based on the previous table extracted from the 167* device 168* 169* index 170* The index of the pkey within the block 171* 172* is_new 173* TRUE for new P_Keys such that the block and index are invalid 174* in that case 175* 176*********/ 177 178/****f* OpenSM: osm_pkey_tbl_construct 179* NAME 180* osm_pkey_tbl_construct 181* 182* DESCRIPTION 183* Constructs the PKey table object 184* 185* SYNOPSIS 186*/ 187void osm_pkey_tbl_construct(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_init 197* NAME 198* osm_pkey_tbl_init 199* 200* DESCRIPTION 201* Inits the PKey table object 202* 203* SYNOPSIS 204*/ 205ib_api_status_t osm_pkey_tbl_init(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_tbl_destroy 215* NAME 216* osm_pkey_tbl_destroy 217* 218* DESCRIPTION 219* Destroys the PKey table object 220* 221* SYNOPSIS 222*/ 223void osm_pkey_tbl_destroy(IN osm_pkey_tbl_t * p_pkey_tbl); 224/* 225* p_pkey_tbl 226* [in] Pointer to osm_pkey_tbl_t object. 227* 228* NOTES 229* 230*********/ 231 232/****f* OpenSM: osm_pkey_tbl_get_num_blocks 233* NAME 234* osm_pkey_tbl_get_num_blocks 235* 236* DESCRIPTION 237* Obtain the number of blocks in IB PKey table 238* 239* SYNOPSIS 240*/ 241static inline uint16_t 242osm_pkey_tbl_get_num_blocks(IN const osm_pkey_tbl_t * p_pkey_tbl) 243{ 244 return ((uint16_t) (cl_ptr_vector_get_size(&p_pkey_tbl->blocks))); 245} 246 247/* 248* p_pkey_tbl 249* [in] Pointer to osm_pkey_tbl_t object. 250* 251* RETURN VALUES 252* The IB pkey table of that pkey table element 253* 254* NOTES 255* 256*********/ 257 258/****f* OpenSM: osm_pkey_tbl_block_get 259* NAME 260* osm_pkey_tbl_block_get 261* 262* DESCRIPTION 263* Obtain the pointer to the IB PKey table block stored in the object 264* 265* SYNOPSIS 266*/ 267static inline ib_pkey_table_t *osm_pkey_tbl_block_get(const osm_pkey_tbl_t * 268 p_pkey_tbl, 269 uint16_t block) 270{ 271 return ((block < cl_ptr_vector_get_size(&p_pkey_tbl->blocks)) ? 272 (ib_pkey_table_t *)cl_ptr_vector_get( 273 &p_pkey_tbl->blocks, block) : NULL); 274}; 275 276/* 277* p_pkey_tbl 278* [in] Pointer to osm_pkey_tbl_t object. 279* 280* block 281* [in] The block number to get 282* 283* RETURN VALUES 284* The IB pkey table of that pkey table element 285* 286* NOTES 287* 288*********/ 289 290/****f* OpenSM: osm_pkey_tbl_new_block_get 291* NAME 292* osm_pkey_tbl_new_block_get 293* 294* DESCRIPTION 295* The same as above but for new block 296* 297* SYNOPSIS 298*/ 299static inline ib_pkey_table_t *osm_pkey_tbl_new_block_get(const osm_pkey_tbl_t * 300 p_pkey_tbl, 301 uint16_t block) 302{ 303 return ((block < cl_ptr_vector_get_size(&p_pkey_tbl->new_blocks)) ? 304 (ib_pkey_table_t *)cl_ptr_vector_get( 305 &p_pkey_tbl->new_blocks, block) : NULL); 306}; 307 308/****f* OpenSM: osm_pkey_find_last_accum_pkey_index 309 * NAME 310 * osm_pkey_find_last_accum_pkey_index 311 * 312 * DESCRIPTION 313 * Finds the next last accumulated pkey 314 * 315 * SYNOPSIS 316 */ 317void osm_pkey_find_last_accum_pkey_index(IN osm_pkey_tbl_t * p_pkey_tbl); 318 319 320/****f* OpenSM: osm_pkey_tbl_set_accum_pkeys 321* NAME 322* osm_pkey_tbl_set_accum_pkeys 323* 324* DESCRIPTION 325* Stores the given pkey and pkey index in the "accum_pkeys" array 326* 327* SYNOPSIS 328*/ 329cl_status_t 330osm_pkey_tbl_set_accum_pkeys(IN osm_pkey_tbl_t * p_pkey_tbl, 331 IN uint16_t pkey, IN uint16_t pkey_idx); 332/* 333* p_pkey_tbl 334* [in] Pointer to the PKey table 335* 336* pkey 337* [in] PKey to store 338* 339* pkey_idx 340* [in] The overall index 341* 342* RETURN VALUES 343* CL_SUCCESS if OK 344* CL_INSUFFICIENT_MEMORY if failed 345* 346*********/ 347 348/****f* OpenSM: osm_pkey_tbl_set_new_entry 349* NAME 350* osm_pkey_tbl_set_new_entry 351* 352* DESCRIPTION 353* Stores the given pkey in the "new" blocks array and update 354* the "map" to show that on the "old" blocks 355* 356* SYNOPSIS 357*/ 358ib_api_status_t 359osm_pkey_tbl_set_new_entry(IN osm_pkey_tbl_t * p_pkey_tbl, 360 IN uint16_t block_idx, 361 IN uint8_t pkey_idx, IN uint16_t pkey); 362/* 363* p_pkey_tbl 364* [in] Pointer to the PKey table 365* 366* block_idx 367* [in] The block index to use 368* 369* pkey_idx 370* [in] The index within the block 371* 372* pkey 373* [in] PKey to store 374* 375* RETURN VALUES 376* IB_SUCCESS if OK 377* IB_ERROR if failed 378* 379*********/ 380 381/****f* OpenSM: osm_pkey_find_next_free_entry 382* NAME 383* osm_pkey_find_next_free_entry 384* 385* DESCRIPTION 386* Find the next free entry in the PKey table starting at the given 387* index and block number. The user should increment pkey_idx before 388* next call 389* Inspect the "new" blocks array for empty space. 390* 391* SYNOPSIS 392*/ 393boolean_t 394osm_pkey_find_next_free_entry(IN osm_pkey_tbl_t * p_pkey_tbl, 395 OUT uint16_t * p_block_idx, 396 OUT uint8_t * p_pkey_idx); 397/* 398* p_pkey_tbl 399* [in] Pointer to the PKey table 400* 401* p_block_idx 402* [out] The block index to use 403* 404* p_pkey_idx 405* [out] The index within the block to use 406* 407* RETURN VALUES 408* TRUE if found 409* FALSE if did not find 410* 411*********/ 412 413/****f* OpenSM: osm_pkey_tbl_init_new_blocks 414* NAME 415* osm_pkey_tbl_init_new_blocks 416* 417* DESCRIPTION 418* Initializes new_blocks vector content (allocate and clear) 419* 420* SYNOPSIS 421*/ 422void osm_pkey_tbl_init_new_blocks(const osm_pkey_tbl_t * p_pkey_tbl); 423/* 424* p_pkey_tbl 425* [in] Pointer to osm_pkey_tbl_t object. 426* 427* NOTES 428* 429*********/ 430 431/****f* OpenSM: osm_pkey_tbl_get_block_and_idx 432* NAME 433* osm_pkey_tbl_get_block_and_idx 434* 435* DESCRIPTION 436* Set the block index and pkey index the given 437* pkey is found in. Return IB_NOT_FOUND if could 438* not find it, IB_SUCCESS if OK 439* 440* SYNOPSIS 441*/ 442ib_api_status_t 443osm_pkey_tbl_get_block_and_idx(IN osm_pkey_tbl_t * p_pkey_tbl, 444 IN uint16_t * p_pkey, 445 OUT uint16_t * block_idx, 446 OUT uint8_t * pkey_index); 447/* 448* p_pkey_tbl 449* [in] Pointer to osm_pkey_tbl_t object. 450* 451* p_pkey 452* [in] Pointer to the P_Key entry searched 453* 454* p_block_idx 455* [out] Pointer to the block index to be updated 456* 457* p_pkey_idx 458* [out] Pointer to the pkey index (in the block) to be updated 459* 460* NOTES 461* 462*********/ 463 464/****f* OpenSM: osm_pkey_tbl_set 465* NAME 466* osm_pkey_tbl_set 467* 468* DESCRIPTION 469* Set the PKey table block provided in the PKey object. 470* 471* SYNOPSIS 472*/ 473ib_api_status_t 474osm_pkey_tbl_set(IN osm_pkey_tbl_t * p_pkey_tbl, 475 IN uint16_t block, IN ib_pkey_table_t * p_tbl, 476 IN boolean_t allow_both_pkeys); 477/* 478* p_pkey_tbl 479* [in] Pointer to osm_pkey_tbl_t object 480* 481* block 482* [in] The block number to set 483* 484* p_tbl 485* [in] The IB PKey block to copy to the object 486* 487* allow_both_pkeys 488* [in] Whether both full and limited membership on same partition 489* are allowed 490* 491* RETURN VALUES 492* IB_SUCCESS or IB_ERROR 493* 494* NOTES 495* 496*********/ 497 498/****f* OpenSM: osm_physp_share_this_pkey 499* NAME 500* osm_physp_share_this_pkey 501* 502* DESCRIPTION 503* Checks if the given physical ports share the specified pkey. 504* 505* SYNOPSIS 506*/ 507boolean_t osm_physp_share_this_pkey(IN const struct osm_physp * p_physp1, 508 IN const struct osm_physp * p_physp2, 509 IN ib_net16_t pkey, 510 IN boolean_t allow_both_pkeys); 511/* 512* PARAMETERS 513* 514* p_physp1 515* [in] Pointer to an osm_physp_t object. 516* 517* p_physp2 518* [in] Pointer to an osm_physp_t object. 519* 520* pkey 521* [in] value of P_Key to check. 522* 523* allow_both_pkeys 524* [in] whether both pkeys allowed policy is being used. 525* 526* RETURN VALUES 527* Returns TRUE if the two ports are matching. 528* FALSE otherwise. 529* 530* NOTES 531* 532*********/ 533 534/****f* OpenSM: osm_physp_find_common_pkey 535* NAME 536* osm_physp_find_common_pkey 537* 538* DESCRIPTION 539* Returns first matching P_Key values for specified physical ports. 540* 541* SYNOPSIS 542*/ 543ib_net16_t osm_physp_find_common_pkey(IN const struct osm_physp *p_physp1, 544 IN const struct osm_physp *p_physp2, 545 IN boolean_t allow_both_pkeys); 546/* 547* PARAMETERS 548* 549* p_physp1 550* [in] Pointer to an osm_physp_t object. 551* 552* p_physp2 553* [in] Pointer to an osm_physp_t object. 554* 555* allow_both_pkeys 556* [in] Whether both full and limited membership on same partition 557* are allowed 558* 559* RETURN VALUES 560* Returns value of first shared P_Key or INVALID P_Key (0x0) if not 561* found. 562* 563* NOTES 564* 565*********/ 566 567/****f* OpenSM: osm_physp_share_pkey 568* NAME 569* osm_physp_share_pkey 570* 571* DESCRIPTION 572* Checks if the given physical ports share a pkey. 573* The meaning P_Key matching: 574* 10.9.3 : 575* In the following, let M_P_Key(Message P_Key) be the P_Key in the incoming 576* packet and E_P_Key(Endnode P_Key) be the P_Key it is being compared against 577* in the packet's destination endnode. 578* 579* If: 580* * neither M_P_Key nor E_P_Key are the invalid P_Key 581* * and the low-order 15 bits of the M_P_Key match the low order 15 582* bits of the E_P_Key 583* * and the high order bit(membership type) of both the M_P_Key and 584* E_P_Key are not both 0 (i.e., both are not Limited members of 585* the partition) 586* 587* then the P_Keys are said to match. 588* 589* SYNOPSIS 590*/ 591boolean_t osm_physp_share_pkey(IN osm_log_t * p_log, 592 IN const struct osm_physp * p_physp_1, 593 IN const struct osm_physp * p_physp_2, 594 IN boolean_t allow_both_pkeys); 595 596/* 597* PARAMETERS 598* p_log 599* [in] Pointer to a log object. 600* 601* p_physp_1 602* [in] Pointer to an osm_physp_t object. 603* 604* p_physp_2 605* [in] Pointer to an osm_physp_t object. 606* 607* allow_both_pkeys 608* [in] Whether both full and limited membership on same partition 609* are allowed 610* 611* RETURN VALUES 612* Returns TRUE if the 2 physical ports are matching. 613* FALSE otherwise. 614* 615* NOTES 616* 617*********/ 618 619/****f* OpenSM: osm_port_share_pkey 620* NAME 621* osm_port_share_pkey 622* 623* DESCRIPTION 624* Checks if the given ports (on their default physical port) share a pkey. 625* The meaning P_Key matching: 626* 10.9.3 : 627* In the following, let M_P_Key(Message P_Key) be the P_Key in the incoming 628* packet and E_P_Key(Endnode P_Key) be the P_Key it is being compared against 629* in the packet's destination endnode. 630* 631* If: 632* * neither M_P_Key nor E_P_Key are the invalid P_Key 633* * and the low-order 15 bits of the M_P_Key match the low order 15 634* bits of the E_P_Key 635* * and the high order bit(membership type) of both the M_P_Key and 636* E_P_Key are not both 0 (i.e., both are not Limited members of 637* the partition) 638* 639* then the P_Keys are said to match. 640* 641* SYNOPSIS 642*/ 643boolean_t osm_port_share_pkey(IN osm_log_t * p_log, 644 IN const struct osm_port * p_port_1, 645 IN const struct osm_port * p_port_2, 646 IN boolean_t allow_both_pkeys); 647 648/* 649* PARAMETERS 650* p_log 651* [in] Pointer to a log object. 652* 653* p_port_1 654* [in] Pointer to an osm_port_t object. 655* 656* p_port_2 657* [in] Pointer to an osm_port_t object. 658* 659* RETURN VALUES 660* Returns TRUE if the 2 ports are matching. 661* FALSE otherwise. 662* 663* NOTES 664* 665*********/ 666 667/****f* OpenSM: osm_physp_has_pkey 668* NAME 669* osm_physp_has_pkey 670* 671* DESCRIPTION 672* Given a physp and a pkey, check if pkey exists in physp pkey table 673* 674* SYNOPSIS 675*/ 676boolean_t osm_physp_has_pkey(IN osm_log_t * p_log, IN ib_net16_t pkey, 677 IN const struct osm_physp *p_physp); 678 679/* 680* PARAMETERS 681* p_log 682* [in] Pointer to a log object. 683* 684* pkey 685* [in] pkey number to look for. 686* 687* p_physp 688* [in] Pointer to osm_physp_t object. 689* 690* RETURN VALUES 691* Returns TRUE if the p_physp has the pkey given. False otherwise. 692* 693* NOTES 694* 695*********/ 696 697/****f* OpenSM: osm_pkey_tbl_set_indx0_pkey 698* NAME 699* osm_pkey_tbl_set_indx0_pkey 700* 701* DESCRIPTION 702* Sets given pkey at index0 in given pkey_tbl. 703* 704* SYNOPSIS 705*/ 706void osm_pkey_tbl_set_indx0_pkey(IN osm_log_t * p_log, IN ib_net16_t pkey, 707 IN boolean_t full, 708 OUT osm_pkey_tbl_t * p_pkey_tbl); 709/* 710* PARAMETERS 711* p_log 712* [in] Pointer to a log object. 713* 714* pkey 715* [in] P_Key. 716* 717* full 718* [in] Indication if this is a full/limited membership pkey. 719* 720* p_pkey_tbl 721* [out] Pointer to osm_pkey_tbl_t object in which to set indx0 pkey. 722* 723* RETURN VALUES 724* None 725* 726* NOTES 727* 728*********/ 729END_C_DECLS 730#endif /* _OSM_PKEY_H_ */ 731