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 55 BEGIN_C_DECLS 56 /* 57 Forward references. 58 */ 59 struct osm_physp; 60 struct osm_port; 61 struct osm_subn; 62 struct osm_node; 63 struct 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 */ 84 typedef 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 */ 153 typedef 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 */ 187 void 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 */ 205 ib_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 */ 223 void 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 */ 241 static inline uint16_t 242 osm_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 */ 267 static 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 */ 299 static 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 */ 317 void 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 */ 329 cl_status_t 330 osm_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 */ 358 ib_api_status_t 359 osm_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 */ 393 boolean_t 394 osm_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 */ 422 void 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 */ 442 ib_api_status_t 443 osm_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 */ 473 ib_api_status_t 474 osm_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 */ 507 boolean_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 */ 543 ib_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 */ 591 boolean_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 */ 643 boolean_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 */ 676 boolean_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 */ 706 void 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 *********/ 729 END_C_DECLS 730 #endif /* _OSM_PKEY_H_ */ 731