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.
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:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
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.
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
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>
47 # define BEGIN_C_DECLS extern "C" {
48 # define END_C_DECLS }
49 #else /* !__cplusplus */
50 # define BEGIN_C_DECLS
52 #endif /* __cplusplus */
66 * Declaration of pkey manipulation functions.
69 /****s* OpenSM: osm_pkey_tbl_t
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
78 * The osm_pkey_tbl_t object should be treated as opaque and should
79 * be manipulated only through the provided functions.
83 typedef struct osm_pkeybl {
84 cl_ptr_vector_t blocks;
85 cl_ptr_vector_t new_blocks;
94 * The IBA defined blocks of pkey values, updated from the subnet
97 * The blocks of pkey values, will be used for updates by SM
100 * A set holding all keys
103 * A list of osm_pending_pkey structs that is temporarily set by
104 * the pkey mgr and used during pkey mgr algorithm only
107 * Tracks the number of blocks having non-zero pkeys
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
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.
120 * The only pkey values stored in 'blocks' vector will be mapped with
125 /****s* OpenSM: osm_pending_pkey_t
130 * This objects stores temporary information on pkeys, their target block,
131 * and index during the pkey manager operation
135 typedef struct osm_pending_pkey {
136 cl_list_item_t list_item;
141 } osm_pending_pkey_t;
148 * The block index based on the previous table extracted from the
152 * The index of the pkey within the block
155 * TRUE for new P_Keys such that the block and index are invalid
160 /****f* OpenSM: osm_pkey_tbl_construct
162 * osm_pkey_tbl_construct
165 * Constructs the PKey table object
169 void osm_pkey_tbl_construct(IN osm_pkey_tbl_t * p_pkey_tbl);
172 * [in] Pointer to osm_pkey_tbl_t object.
178 /****f* OpenSM: osm_pkey_tbl_init
183 * Inits the PKey table object
187 ib_api_status_t osm_pkey_tbl_init(IN osm_pkey_tbl_t * p_pkey_tbl);
190 * [in] Pointer to osm_pkey_tbl_t object.
196 /****f* OpenSM: osm_pkey_tbl_destroy
198 * osm_pkey_tbl_destroy
201 * Destroys the PKey table object
205 void osm_pkey_tbl_destroy(IN osm_pkey_tbl_t * p_pkey_tbl);
208 * [in] Pointer to osm_pkey_tbl_t object.
214 /****f* OpenSM: osm_pkey_get_num_blocks
216 * osm_pkey_get_num_blocks
219 * Obtain the number of blocks in IB PKey table
223 static inline uint16_t
224 osm_pkey_tbl_get_num_blocks(IN const osm_pkey_tbl_t * p_pkey_tbl)
226 return ((uint16_t) (cl_ptr_vector_get_size(&p_pkey_tbl->blocks)));
231 * [in] Pointer to osm_pkey_tbl_t object.
234 * The IB pkey table of that pkey table element
240 /****f* OpenSM: osm_pkey_tbl_block_get
242 * osm_pkey_tbl_block_get
245 * Obtain the pointer to the IB PKey table block stored in the object
249 static inline ib_pkey_table_t *osm_pkey_tbl_block_get(const osm_pkey_tbl_t *
253 return ((block < cl_ptr_vector_get_size(&p_pkey_tbl->blocks)) ?
254 cl_ptr_vector_get(&p_pkey_tbl->blocks, block) : NULL);
259 * [in] Pointer to osm_pkey_tbl_t object.
262 * [in] The lock number to get
265 * The IB pkey table of that pkey table element
271 /****f* OpenSM: osm_pkey_tbl_new_block_get
273 * osm_pkey_tbl_new_block_get
276 * The same as above but for new block
280 static inline ib_pkey_table_t *osm_pkey_tbl_new_block_get(const osm_pkey_tbl_t *
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;
288 /****f* OpenSM: osm_pkey_tbl_set_new_entry
290 * osm_pkey_tbl_set_new_entry
293 * Stores the given pkey in the "new" blocks array and update
294 * the "map" to show that on the "old" blocks
299 osm_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);
304 * [in] Pointer to the PKey table
307 * [in] The block index to use
310 * [in] The index within the block
321 /****f* OpenSM: osm_pkey_find_next_free_entry
323 * osm_pkey_find_next_free_entry
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
329 * Inspect the "new" blocks array for empty space.
334 osm_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);
339 * [in] Pointer to the PKey table
342 * [out] The block index to use
345 * [out] The index within the block to use
349 * FALSE if did not find
353 /****f* OpenSM: osm_pkey_tbl_init_new_blocks
355 * osm_pkey_tbl_init_new_blocks
358 * Initializes new_blocks vector content (allocate and clear)
362 void osm_pkey_tbl_init_new_blocks(const osm_pkey_tbl_t * p_pkey_tbl);
365 * [in] Pointer to osm_pkey_tbl_t object.
371 /****f* OpenSM: osm_pkey_tbl_get_block_and_idx
373 * osm_pkey_tbl_get_block_and_idx
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
383 osm_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);
389 * [in] Pointer to osm_pkey_tbl_t object.
392 * [in] Pointer to the P_Key entry searched
395 * [out] Pointer to the block index to be updated
398 * [out] Pointer to the pkey index (in the block) to be updated
404 /****f* OpenSM: osm_pkey_tbl_set
409 * Set the PKey table block provided in the PKey object.
414 osm_pkey_tbl_set(IN osm_pkey_tbl_t * p_pkey_tbl,
415 IN uint16_t block, IN ib_pkey_table_t * p_tbl);
418 * [in] Pointer to osm_pkey_tbl_t object.
421 * [in] The block number to set
424 * [in] The IB PKey block to copy to the object
427 * IB_SUCCESS or IB_ERROR
433 /****f* OpenSM: osm_physp_share_this_pkey
435 * osm_physp_share_this_pkey
438 * Checks if the given physical ports share the specified pkey.
442 boolean_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);
449 * [in] Pointer to an osm_physp_t object.
452 * [in] Pointer to an osm_physp_t object.
455 * [in] value of P_Key to check.
458 * Returns TRUE if the two ports are matching.
465 /****f* OpenSM: osm_physp_find_common_pkey
467 * osm_physp_find_common_pkey
470 * Returns first matching P_Key values for specified physical ports.
474 ib_net16_t osm_physp_find_common_pkey(IN const struct osm_physp *const
476 IN const struct osm_physp *const
482 * [in] Pointer to an osm_physp_t object.
485 * [in] Pointer to an osm_physp_t object.
488 * Returns value of first shared P_Key or INVALID P_Key (0x0) if not
495 /****f* OpenSM: osm_physp_share_pkey
497 * osm_physp_share_pkey
500 * Checks if the given physical ports share a pkey.
501 * The meaning P_Key matching:
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.
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
515 * then the P_Keys are said to match.
519 boolean_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);
526 * [in] Pointer to a log object.
529 * [in] Pointer to an osm_physp_t object.
532 * [in] Pointer to an osm_physp_t object.
535 * Returns TRUE if the 2 physical ports are matching.
542 /****f* OpenSM: osm_port_share_pkey
544 * osm_port_share_pkey
547 * Checks if the given ports (on their default physical port) share a pkey.
548 * The meaning P_Key matching:
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.
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
562 * then the P_Keys are said to match.
566 boolean_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);
573 * [in] Pointer to a log object.
576 * [in] Pointer to an osm_port_t object.
579 * [in] Pointer to an osm_port_t object.
582 * Returns TRUE if the 2 ports are matching.
589 /****f* OpenSM: osm_physp_has_pkey
594 * Checks if the given lids and port_numbers share a pkey.
595 * The meaning P_Key matching:
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.
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
609 * then the P_Keys are said to match.
613 boolean_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);
620 * [in] Pointer to a log object.
623 * [in] pkey number to look for.
626 * [in] Pointer to osm_physp_t object.
629 * Returns TRUE if the p_physp has the pkey given. False otherwise.
636 #endif /* _OSM_PKEY_H_ */