1219820Sjeff/*
2219820Sjeff * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3219820Sjeff * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved.
4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5219820Sjeff *
6219820Sjeff * This software is available to you under a choice of one of two
7219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
8219820Sjeff * General Public License (GPL) Version 2, available from the file
9219820Sjeff * COPYING in the main directory of this source tree, or the
10219820Sjeff * OpenIB.org BSD license below:
11219820Sjeff *
12219820Sjeff *     Redistribution and use in source and binary forms, with or
13219820Sjeff *     without modification, are permitted provided that the following
14219820Sjeff *     conditions are met:
15219820Sjeff *
16219820Sjeff *      - Redistributions of source code must retain the above
17219820Sjeff *        copyright notice, this list of conditions and the following
18219820Sjeff *        disclaimer.
19219820Sjeff *
20219820Sjeff *      - Redistributions in binary form must reproduce the above
21219820Sjeff *        copyright notice, this list of conditions and the following
22219820Sjeff *        disclaimer in the documentation and/or other materials
23219820Sjeff *        provided with the distribution.
24219820Sjeff *
25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32219820Sjeff * SOFTWARE.
33219820Sjeff *
34219820Sjeff */
35219820Sjeff
36219820Sjeff/*
37219820Sjeff * Abstract:
38219820Sjeff *    Implementation of opensm pkey manipulation functions.
39219820Sjeff */
40219820Sjeff
41219820Sjeff#if HAVE_CONFIG_H
42219820Sjeff#  include <config.h>
43219820Sjeff#endif				/* HAVE_CONFIG_H */
44219820Sjeff
45219820Sjeff#include <stdlib.h>
46219820Sjeff#include <stdio.h>
47219820Sjeff#include <string.h>
48219820Sjeff#include <complib/cl_debug.h>
49219820Sjeff#include <iba/ib_types.h>
50219820Sjeff#include <opensm/osm_pkey.h>
51219820Sjeff#include <opensm/osm_log.h>
52219820Sjeff#include <opensm/osm_port.h>
53219820Sjeff#include <opensm/osm_node.h>
54219820Sjeff#include <opensm/osm_switch.h>
55219820Sjeff#include <opensm/osm_helper.h>
56219820Sjeff
57219820Sjeff/**********************************************************************
58219820Sjeff **********************************************************************/
59219820Sjeffvoid osm_pkey_tbl_construct(IN osm_pkey_tbl_t * p_pkey_tbl)
60219820Sjeff{
61219820Sjeff	cl_ptr_vector_construct(&p_pkey_tbl->blocks);
62219820Sjeff	cl_ptr_vector_construct(&p_pkey_tbl->new_blocks);
63219820Sjeff	cl_map_construct(&p_pkey_tbl->keys);
64219820Sjeff}
65219820Sjeff
66219820Sjeff/**********************************************************************
67219820Sjeff **********************************************************************/
68219820Sjeffvoid osm_pkey_tbl_destroy(IN osm_pkey_tbl_t * p_pkey_tbl)
69219820Sjeff{
70219820Sjeff	ib_pkey_table_t *p_block;
71219820Sjeff	uint16_t num_blocks, i;
72219820Sjeff
73219820Sjeff	num_blocks = (uint16_t) (cl_ptr_vector_get_size(&p_pkey_tbl->blocks));
74219820Sjeff	for (i = 0; i < num_blocks; i++)
75219820Sjeff		if ((p_block = cl_ptr_vector_get(&p_pkey_tbl->blocks, i)))
76219820Sjeff			free(p_block);
77219820Sjeff	cl_ptr_vector_destroy(&p_pkey_tbl->blocks);
78219820Sjeff
79219820Sjeff	num_blocks =
80219820Sjeff	    (uint16_t) (cl_ptr_vector_get_size(&p_pkey_tbl->new_blocks));
81219820Sjeff	for (i = 0; i < num_blocks; i++)
82219820Sjeff		if ((p_block = cl_ptr_vector_get(&p_pkey_tbl->new_blocks, i)))
83219820Sjeff			free(p_block);
84219820Sjeff	cl_ptr_vector_destroy(&p_pkey_tbl->new_blocks);
85219820Sjeff
86219820Sjeff	cl_map_remove_all(&p_pkey_tbl->keys);
87219820Sjeff	cl_map_destroy(&p_pkey_tbl->keys);
88219820Sjeff}
89219820Sjeff
90219820Sjeff/**********************************************************************
91219820Sjeff **********************************************************************/
92219820Sjeffib_api_status_t osm_pkey_tbl_init(IN osm_pkey_tbl_t * p_pkey_tbl)
93219820Sjeff{
94219820Sjeff	cl_ptr_vector_init(&p_pkey_tbl->blocks, 0, 1);
95219820Sjeff	cl_ptr_vector_init(&p_pkey_tbl->new_blocks, 0, 1);
96219820Sjeff	cl_map_init(&p_pkey_tbl->keys, 1);
97219820Sjeff	cl_qlist_init(&p_pkey_tbl->pending);
98219820Sjeff	p_pkey_tbl->used_blocks = 0;
99219820Sjeff	p_pkey_tbl->max_blocks = 0;
100219820Sjeff	return (IB_SUCCESS);
101219820Sjeff}
102219820Sjeff
103219820Sjeff/**********************************************************************
104219820Sjeff **********************************************************************/
105219820Sjeffvoid osm_pkey_tbl_init_new_blocks(IN const osm_pkey_tbl_t * p_pkey_tbl)
106219820Sjeff{
107219820Sjeff	ib_pkey_table_t *p_block;
108219820Sjeff	size_t b, num_blocks = cl_ptr_vector_get_size(&p_pkey_tbl->new_blocks);
109219820Sjeff
110219820Sjeff	for (b = 0; b < num_blocks; b++)
111219820Sjeff		if ((p_block = cl_ptr_vector_get(&p_pkey_tbl->new_blocks, b)))
112219820Sjeff			memset(p_block, 0, sizeof(*p_block));
113219820Sjeff}
114219820Sjeff
115219820Sjeff/**********************************************************************
116219820Sjeff **********************************************************************/
117219820Sjeffvoid osm_pkey_tbl_cleanup_pending(IN osm_pkey_tbl_t * p_pkey_tbl)
118219820Sjeff{
119219820Sjeff	cl_list_item_t *p_item;
120219820Sjeff
121219820Sjeff	p_item = cl_qlist_remove_head(&p_pkey_tbl->pending);
122219820Sjeff	while (p_item != cl_qlist_end(&p_pkey_tbl->pending)) {
123219820Sjeff		free((osm_pending_pkey_t *) p_item);
124219820Sjeff	}
125219820Sjeff}
126219820Sjeff
127219820Sjeff/**********************************************************************
128219820Sjeff **********************************************************************/
129219820Sjeffib_api_status_t
130219820Sjeffosm_pkey_tbl_set(IN osm_pkey_tbl_t * p_pkey_tbl,
131219820Sjeff		 IN uint16_t block, IN ib_pkey_table_t * p_tbl)
132219820Sjeff{
133219820Sjeff	uint16_t b, i;
134219820Sjeff	ib_pkey_table_t *p_pkey_block;
135219820Sjeff	uint16_t *p_prev_pkey;
136219820Sjeff	ib_net16_t pkey;
137219820Sjeff
138219820Sjeff	/* make sure the block is allocated */
139219820Sjeff	if (cl_ptr_vector_get_size(&p_pkey_tbl->blocks) > block)
140219820Sjeff		p_pkey_block =
141219820Sjeff		    (ib_pkey_table_t *) cl_ptr_vector_get(&p_pkey_tbl->blocks,
142219820Sjeff							  block);
143219820Sjeff	else
144219820Sjeff		p_pkey_block = NULL;
145219820Sjeff
146219820Sjeff	if (!p_pkey_block) {
147219820Sjeff		p_pkey_block =
148219820Sjeff		    (ib_pkey_table_t *) malloc(sizeof(ib_pkey_table_t));
149219820Sjeff		if (!p_pkey_block)
150219820Sjeff			return (IB_ERROR);
151219820Sjeff		memset(p_pkey_block, 0, sizeof(ib_pkey_table_t));
152219820Sjeff		cl_ptr_vector_set(&p_pkey_tbl->blocks, block, p_pkey_block);
153219820Sjeff	}
154219820Sjeff
155219820Sjeff	/* sets the block values */
156219820Sjeff	memcpy(p_pkey_block, p_tbl, sizeof(ib_pkey_table_t));
157219820Sjeff
158219820Sjeff	/*
159219820Sjeff	   NOTE: as the spec does not require uniqueness of PKeys in
160219820Sjeff	   tables there is no other way but to refresh the entire keys map.
161219820Sjeff
162219820Sjeff	   Moreover, if the same key exists but with full membership it should
163219820Sjeff	   have precedence on the key with limited membership !
164219820Sjeff	 */
165219820Sjeff	cl_map_remove_all(&p_pkey_tbl->keys);
166219820Sjeff
167219820Sjeff	for (b = 0; b < cl_ptr_vector_get_size(&p_pkey_tbl->blocks); b++) {
168219820Sjeff
169219820Sjeff		p_pkey_block = cl_ptr_vector_get(&p_pkey_tbl->blocks, b);
170219820Sjeff		if (!p_pkey_block)
171219820Sjeff			continue;
172219820Sjeff
173219820Sjeff		for (i = 0; i < IB_NUM_PKEY_ELEMENTS_IN_BLOCK; i++) {
174219820Sjeff			pkey = p_pkey_block->pkey_entry[i];
175219820Sjeff			if (ib_pkey_is_invalid(pkey))
176219820Sjeff				continue;
177219820Sjeff
178219820Sjeff			/*
179219820Sjeff			   ignore the PKey Full Member bit in the key but store
180219820Sjeff			   the pointer to the table element as the map value
181219820Sjeff			 */
182219820Sjeff			p_prev_pkey =
183219820Sjeff			    cl_map_get(&p_pkey_tbl->keys,
184219820Sjeff				       ib_pkey_get_base(pkey));
185219820Sjeff
186219820Sjeff			/* we only insert if no previous or it is not full member */
187219820Sjeff			if ((p_prev_pkey == NULL) ||
188219820Sjeff			    (cl_ntoh16(*p_prev_pkey) < cl_ntoh16(pkey)))
189219820Sjeff				cl_map_insert(&p_pkey_tbl->keys,
190219820Sjeff					      ib_pkey_get_base(pkey),
191219820Sjeff					      &(p_pkey_block->pkey_entry[i])
192219820Sjeff				    );
193219820Sjeff		}
194219820Sjeff	}
195219820Sjeff	return (IB_SUCCESS);
196219820Sjeff}
197219820Sjeff
198219820Sjeff/**********************************************************************
199219820Sjeff **********************************************************************/
200219820Sjeff/*
201219820Sjeff  Store the given pkey in the "new" blocks array.
202219820Sjeff  Also, make sure the regular block exists.
203219820Sjeff*/
204219820Sjeffib_api_status_t
205219820Sjeffosm_pkey_tbl_set_new_entry(IN osm_pkey_tbl_t * p_pkey_tbl,
206219820Sjeff			   IN uint16_t block_idx,
207219820Sjeff			   IN uint8_t pkey_idx, IN uint16_t pkey)
208219820Sjeff{
209219820Sjeff	ib_pkey_table_t *p_block;
210219820Sjeff
211219820Sjeff	if (!(p_block = osm_pkey_tbl_new_block_get(p_pkey_tbl, block_idx))) {
212219820Sjeff		p_block = (ib_pkey_table_t *) malloc(sizeof(ib_pkey_table_t));
213219820Sjeff		if (!p_block)
214219820Sjeff			return (IB_ERROR);
215219820Sjeff		memset(p_block, 0, sizeof(ib_pkey_table_t));
216219820Sjeff		cl_ptr_vector_set(&p_pkey_tbl->new_blocks, block_idx, p_block);
217219820Sjeff	}
218219820Sjeff
219219820Sjeff	p_block->pkey_entry[pkey_idx] = pkey;
220219820Sjeff	if (p_pkey_tbl->used_blocks <= block_idx)
221219820Sjeff		p_pkey_tbl->used_blocks = block_idx + 1;
222219820Sjeff
223219820Sjeff	return (IB_SUCCESS);
224219820Sjeff}
225219820Sjeff
226219820Sjeff/**********************************************************************
227219820Sjeff **********************************************************************/
228219820Sjeffboolean_t
229219820Sjeffosm_pkey_find_next_free_entry(IN osm_pkey_tbl_t * p_pkey_tbl,
230219820Sjeff			      OUT uint16_t * p_block_idx,
231219820Sjeff			      OUT uint8_t * p_pkey_idx)
232219820Sjeff{
233219820Sjeff	ib_pkey_table_t *p_new_block;
234219820Sjeff
235219820Sjeff	CL_ASSERT(p_block_idx);
236219820Sjeff	CL_ASSERT(p_pkey_idx);
237219820Sjeff
238219820Sjeff	while (*p_block_idx < p_pkey_tbl->max_blocks) {
239219820Sjeff		if (*p_pkey_idx > IB_NUM_PKEY_ELEMENTS_IN_BLOCK - 1) {
240219820Sjeff			*p_pkey_idx = 0;
241219820Sjeff			(*p_block_idx)++;
242219820Sjeff			if (*p_block_idx >= p_pkey_tbl->max_blocks)
243219820Sjeff				return FALSE;
244219820Sjeff		}
245219820Sjeff
246219820Sjeff		p_new_block =
247219820Sjeff		    osm_pkey_tbl_new_block_get(p_pkey_tbl, *p_block_idx);
248219820Sjeff
249219820Sjeff		if (!p_new_block ||
250219820Sjeff		    ib_pkey_is_invalid(p_new_block->pkey_entry[*p_pkey_idx]))
251219820Sjeff			return TRUE;
252219820Sjeff		else
253219820Sjeff			(*p_pkey_idx)++;
254219820Sjeff	}
255219820Sjeff	return FALSE;
256219820Sjeff}
257219820Sjeff
258219820Sjeff/**********************************************************************
259219820Sjeff **********************************************************************/
260219820Sjeffib_api_status_t
261219820Sjeffosm_pkey_tbl_get_block_and_idx(IN osm_pkey_tbl_t * p_pkey_tbl,
262219820Sjeff			       IN uint16_t * p_pkey,
263219820Sjeff			       OUT uint16_t * p_block_idx,
264219820Sjeff			       OUT uint8_t * p_pkey_idx)
265219820Sjeff{
266219820Sjeff	uint16_t num_of_blocks;
267219820Sjeff	uint16_t block_index;
268219820Sjeff	ib_pkey_table_t *block;
269219820Sjeff
270219820Sjeff	CL_ASSERT(p_block_idx != NULL);
271219820Sjeff	CL_ASSERT(p_pkey_idx != NULL);
272219820Sjeff
273219820Sjeff	num_of_blocks = (uint16_t) cl_ptr_vector_get_size(&p_pkey_tbl->blocks);
274219820Sjeff	for (block_index = 0; block_index < num_of_blocks; block_index++) {
275219820Sjeff		block = osm_pkey_tbl_block_get(p_pkey_tbl, block_index);
276219820Sjeff		if ((block->pkey_entry <= p_pkey) &&
277219820Sjeff		    (p_pkey <
278219820Sjeff		     block->pkey_entry + IB_NUM_PKEY_ELEMENTS_IN_BLOCK)) {
279219820Sjeff			*p_block_idx = block_index;
280219820Sjeff			*p_pkey_idx = (uint8_t) (p_pkey - block->pkey_entry);
281219820Sjeff			return (IB_SUCCESS);
282219820Sjeff		}
283219820Sjeff	}
284219820Sjeff	return (IB_NOT_FOUND);
285219820Sjeff}
286219820Sjeff
287219820Sjeff/**********************************************************************
288219820Sjeff **********************************************************************/
289219820Sjeffstatic boolean_t
290219820Sjeff__osm_match_pkey(IN const ib_net16_t * pkey1, IN const ib_net16_t * pkey2)
291219820Sjeff{
292219820Sjeff
293219820Sjeff	/* if both pkeys are not full member - this is not a match */
294219820Sjeff	if (!(ib_pkey_is_full_member(*pkey1) || ib_pkey_is_full_member(*pkey2)))
295219820Sjeff		return (FALSE);
296219820Sjeff
297219820Sjeff	/* compare if the bases are the same. if they are - then
298219820Sjeff	   this is a match */
299219820Sjeff	if (ib_pkey_get_base(*pkey1) != ib_pkey_get_base(*pkey2))
300219820Sjeff		return (FALSE);
301219820Sjeff
302219820Sjeff	return (TRUE);
303219820Sjeff}
304219820Sjeff
305219820Sjeff/**********************************************************************
306219820Sjeff **********************************************************************/
307219820Sjeffboolean_t
308219820Sjeffosm_physp_share_this_pkey(IN const osm_physp_t * const p_physp1,
309219820Sjeff			  IN const osm_physp_t * const p_physp2,
310219820Sjeff			  IN const ib_net16_t pkey)
311219820Sjeff{
312219820Sjeff	ib_net16_t *pkey1, *pkey2;
313219820Sjeff
314219820Sjeff	pkey1 = cl_map_get(&(osm_physp_get_pkey_tbl(p_physp1))->keys,
315219820Sjeff			   ib_pkey_get_base(pkey));
316219820Sjeff	pkey2 = cl_map_get(&(osm_physp_get_pkey_tbl(p_physp2))->keys,
317219820Sjeff			   ib_pkey_get_base(pkey));
318219820Sjeff	return (pkey1 && pkey2 && __osm_match_pkey(pkey1, pkey2));
319219820Sjeff}
320219820Sjeff
321219820Sjeff/**********************************************************************
322219820Sjeff **********************************************************************/
323219820Sjeffib_net16_t
324219820Sjeffosm_physp_find_common_pkey(IN const osm_physp_t * const p_physp1,
325219820Sjeff			   IN const osm_physp_t * const p_physp2)
326219820Sjeff{
327219820Sjeff	ib_net16_t *pkey1, *pkey2;
328219820Sjeff	uint64_t pkey1_base, pkey2_base;
329219820Sjeff	const osm_pkey_tbl_t *pkey_tbl1, *pkey_tbl2;
330219820Sjeff	cl_map_iterator_t map_iter1, map_iter2;
331219820Sjeff
332219820Sjeff	pkey_tbl1 = osm_physp_get_pkey_tbl(p_physp1);
333219820Sjeff	pkey_tbl2 = osm_physp_get_pkey_tbl(p_physp2);
334219820Sjeff
335219820Sjeff	map_iter1 = cl_map_head(&pkey_tbl1->keys);
336219820Sjeff	map_iter2 = cl_map_head(&pkey_tbl2->keys);
337219820Sjeff
338219820Sjeff	/* we rely on the fact the map are sorted by pkey */
339219820Sjeff	while ((map_iter1 != cl_map_end(&pkey_tbl1->keys)) &&
340219820Sjeff	       (map_iter2 != cl_map_end(&pkey_tbl2->keys))) {
341219820Sjeff		pkey1 = (ib_net16_t *) cl_map_obj(map_iter1);
342219820Sjeff		pkey2 = (ib_net16_t *) cl_map_obj(map_iter2);
343219820Sjeff
344219820Sjeff		if (__osm_match_pkey(pkey1, pkey2))
345219820Sjeff			return *pkey1;
346219820Sjeff
347219820Sjeff		/* advance the lower value if they are not equal */
348219820Sjeff		pkey1_base = cl_map_key(map_iter1);
349219820Sjeff		pkey2_base = cl_map_key(map_iter2);
350219820Sjeff		if (pkey2_base == pkey1_base) {
351219820Sjeff			map_iter1 = cl_map_next(map_iter1);
352219820Sjeff			map_iter2 = cl_map_next(map_iter2);
353219820Sjeff		} else if (pkey2_base < pkey1_base)
354219820Sjeff			map_iter2 = cl_map_next(map_iter2);
355219820Sjeff		else
356219820Sjeff			map_iter1 = cl_map_next(map_iter1);
357219820Sjeff	}
358219820Sjeff
359219820Sjeff	return 0;
360219820Sjeff}
361219820Sjeff
362219820Sjeff/**********************************************************************
363219820Sjeff **********************************************************************/
364219820Sjeffboolean_t
365219820Sjeffosm_physp_share_pkey(IN osm_log_t * p_log,
366219820Sjeff		     IN const osm_physp_t * const p_physp_1,
367219820Sjeff		     IN const osm_physp_t * const p_physp_2)
368219820Sjeff{
369219820Sjeff	const osm_pkey_tbl_t *pkey_tbl1, *pkey_tbl2;
370219820Sjeff
371219820Sjeff	if (p_physp_1 == p_physp_2)
372219820Sjeff		return TRUE;
373219820Sjeff
374219820Sjeff	pkey_tbl1 = osm_physp_get_pkey_tbl(p_physp_1);
375219820Sjeff	pkey_tbl2 = osm_physp_get_pkey_tbl(p_physp_2);
376219820Sjeff
377219820Sjeff	/*
378219820Sjeff	   The spec: 10.9.2 does not require each phys port to have PKey Table.
379219820Sjeff	   So actually if it does not, we need to use the default port instead.
380219820Sjeff
381219820Sjeff	   HACK: meanwhile we will ignore the check
382219820Sjeff	 */
383219820Sjeff	if (cl_is_map_empty(&pkey_tbl1->keys)
384219820Sjeff	    || cl_is_map_empty(&pkey_tbl2->keys))
385219820Sjeff		return TRUE;
386219820Sjeff
387219820Sjeff	return
388219820Sjeff	    !ib_pkey_is_invalid(osm_physp_find_common_pkey
389219820Sjeff				(p_physp_1, p_physp_2));
390219820Sjeff}
391219820Sjeff
392219820Sjeff/**********************************************************************
393219820Sjeff **********************************************************************/
394219820Sjeffboolean_t
395219820Sjeffosm_port_share_pkey(IN osm_log_t * p_log,
396219820Sjeff		    IN const osm_port_t * const p_port_1,
397219820Sjeff		    IN const osm_port_t * const p_port_2)
398219820Sjeff{
399219820Sjeff
400219820Sjeff	osm_physp_t *p_physp1, *p_physp2;
401219820Sjeff	boolean_t ret;
402219820Sjeff
403219820Sjeff	OSM_LOG_ENTER(p_log);
404219820Sjeff
405219820Sjeff	if (!p_port_1 || !p_port_2) {
406219820Sjeff		ret = FALSE;
407219820Sjeff		goto Exit;
408219820Sjeff	}
409219820Sjeff
410219820Sjeff	p_physp1 = p_port_1->p_physp;
411219820Sjeff	p_physp2 = p_port_2->p_physp;
412219820Sjeff
413219820Sjeff	if (!p_physp1 || !p_physp2) {
414219820Sjeff		ret = FALSE;
415219820Sjeff		goto Exit;
416219820Sjeff	}
417219820Sjeff
418219820Sjeff	ret = osm_physp_share_pkey(p_log, p_physp1, p_physp2);
419219820Sjeff
420219820SjeffExit:
421219820Sjeff	OSM_LOG_EXIT(p_log);
422219820Sjeff	return ret;
423219820Sjeff}
424219820Sjeff
425219820Sjeff/**********************************************************************
426219820Sjeff **********************************************************************/
427219820Sjeffboolean_t
428219820Sjeffosm_physp_has_pkey(IN osm_log_t * p_log,
429219820Sjeff		   IN const ib_net16_t pkey,
430219820Sjeff		   IN const osm_physp_t * const p_physp)
431219820Sjeff{
432219820Sjeff
433219820Sjeff	ib_net16_t *p_pkey, pkey_base;
434219820Sjeff	const osm_pkey_tbl_t *pkey_tbl;
435219820Sjeff	boolean_t res = FALSE;
436219820Sjeff
437219820Sjeff	OSM_LOG_ENTER(p_log);
438219820Sjeff
439219820Sjeff	OSM_LOG(p_log, OSM_LOG_DEBUG,
440219820Sjeff		"Search for PKey: 0x%04x\n", cl_ntoh16(pkey));
441219820Sjeff
442219820Sjeff	/* if the pkey given is an invalid pkey - return TRUE. */
443219820Sjeff	if (ib_pkey_is_invalid(pkey)) {
444219820Sjeff		OSM_LOG(p_log, OSM_LOG_DEBUG,
445219820Sjeff			"Given invalid PKey - we treat it loosely and allow it\n");
446219820Sjeff		res = TRUE;
447219820Sjeff		goto Exit;
448219820Sjeff	}
449219820Sjeff
450219820Sjeff	pkey_base = ib_pkey_get_base(pkey);
451219820Sjeff
452219820Sjeff	pkey_tbl = osm_physp_get_pkey_tbl(p_physp);
453219820Sjeff
454219820Sjeff	p_pkey = cl_map_get(&pkey_tbl->keys, pkey_base);
455219820Sjeff	if (p_pkey) {
456219820Sjeff		res = TRUE;
457219820Sjeff		OSM_LOG(p_log, OSM_LOG_DEBUG,
458219820Sjeff			"PKey 0x%04x was found\n", cl_ntoh16(pkey));
459219820Sjeff	} else {
460219820Sjeff		OSM_LOG(p_log, OSM_LOG_DEBUG,
461219820Sjeff			"PKey 0x%04x was not found\n", cl_ntoh16(pkey));
462219820Sjeff	}
463219820Sjeff
464219820SjeffExit:
465219820Sjeff	OSM_LOG_EXIT(p_log);
466219820Sjeff	return res;
467219820Sjeff}
468