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
osm_pkey_tbl_get_num_blocks(IN const osm_pkey_tbl_t * p_pkey_tbl)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 */
osm_pkey_tbl_block_get(const osm_pkey_tbl_t * p_pkey_tbl,uint16_t block)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 */
osm_pkey_tbl_new_block_get(const osm_pkey_tbl_t * p_pkey_tbl,uint16_t block)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