xref: /illumos-gate/usr/src/uts/common/io/ib/clients/rdsv3/transport.c (revision 6a634c9dca3093f3922e4b7ab826d7bdf17bf78e)
1c0dd49bdSEiji Ota /*
2c0dd49bdSEiji Ota  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3c0dd49bdSEiji Ota  */
4c0dd49bdSEiji Ota 
5c0dd49bdSEiji Ota /*
616e76cddSagiri  * This file contains code imported from the OFED rds source file transport.c
716e76cddSagiri  * Oracle elects to have and use the contents of transport.c under and governed
816e76cddSagiri  * by the OpenIB.org BSD license (see below for full license text). However,
916e76cddSagiri  * the following notice accompanied the original version of this file:
1016e76cddSagiri  */
1116e76cddSagiri 
1216e76cddSagiri /*
13c0dd49bdSEiji Ota  * Copyright (c) 2006 Oracle.  All rights reserved.
14c0dd49bdSEiji Ota  *
15c0dd49bdSEiji Ota  * This software is available to you under a choice of one of two
16c0dd49bdSEiji Ota  * licenses.  You may choose to be licensed under the terms of the GNU
17c0dd49bdSEiji Ota  * General Public License (GPL) Version 2, available from the file
18c0dd49bdSEiji Ota  * COPYING in the main directory of this source tree, or the
19c0dd49bdSEiji Ota  * OpenIB.org BSD license below:
20c0dd49bdSEiji Ota  *
21c0dd49bdSEiji Ota  *     Redistribution and use in source and binary forms, with or
22c0dd49bdSEiji Ota  *     without modification, are permitted provided that the following
23c0dd49bdSEiji Ota  *     conditions are met:
24c0dd49bdSEiji Ota  *
25c0dd49bdSEiji Ota  *      - Redistributions of source code must retain the above
26c0dd49bdSEiji Ota  *        copyright notice, this list of conditions and the following
27c0dd49bdSEiji Ota  *        disclaimer.
28c0dd49bdSEiji Ota  *
29c0dd49bdSEiji Ota  *      - Redistributions in binary form must reproduce the above
30c0dd49bdSEiji Ota  *        copyright notice, this list of conditions and the following
31c0dd49bdSEiji Ota  *        disclaimer in the documentation and/or other materials
32c0dd49bdSEiji Ota  *        provided with the distribution.
33c0dd49bdSEiji Ota  *
34c0dd49bdSEiji Ota  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
35c0dd49bdSEiji Ota  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36c0dd49bdSEiji Ota  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
37c0dd49bdSEiji Ota  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
38c0dd49bdSEiji Ota  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
39c0dd49bdSEiji Ota  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
40c0dd49bdSEiji Ota  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
41c0dd49bdSEiji Ota  * SOFTWARE.
42c0dd49bdSEiji Ota  *
43c0dd49bdSEiji Ota  */
44c0dd49bdSEiji Ota #include <sys/ksynch.h>
45c0dd49bdSEiji Ota #include <sys/list.h>
46c0dd49bdSEiji Ota #include <sys/rds.h>
47c0dd49bdSEiji Ota #include <sys/sysmacros.h>
48c0dd49bdSEiji Ota 
49c0dd49bdSEiji Ota #include <sys/ib/clients/rdsv3/rdsv3.h>
50c0dd49bdSEiji Ota #include <sys/ib/clients/rdsv3/loop.h>
51c0dd49bdSEiji Ota #include <sys/ib/clients/rdsv3/rdsv3_impl.h>
52c0dd49bdSEiji Ota #include <sys/ib/clients/rdsv3/rdsv3_debug.h>
53c0dd49bdSEiji Ota 
54cadbfdc3SEiji Ota struct rdsv3_transport *transports[RDS_TRANS_COUNT];
55c0dd49bdSEiji Ota krwlock_t		trans_sem; /* this was a semaphore */
56c0dd49bdSEiji Ota 
57c0dd49bdSEiji Ota int
rdsv3_trans_register(struct rdsv3_transport * trans)58c0dd49bdSEiji Ota rdsv3_trans_register(struct rdsv3_transport *trans)
59c0dd49bdSEiji Ota {
60c0dd49bdSEiji Ota 	RDSV3_DPRINTF4("rdsv3_trans_register", "Enter(trans: %p)", trans);
61c0dd49bdSEiji Ota 
62c0dd49bdSEiji Ota 	rw_enter(&trans_sem, RW_WRITER);
63c0dd49bdSEiji Ota 
64cadbfdc3SEiji Ota 	if (transports[trans->t_type]) {
65cadbfdc3SEiji Ota 		cmn_err(CE_WARN,
66cadbfdc3SEiji Ota 		    "RDSV3 Transport type %d already registered\n",
67cadbfdc3SEiji Ota 		    trans->t_type);
68cadbfdc3SEiji Ota 		rw_exit(&trans_sem);
69cadbfdc3SEiji Ota 		return (1);
70cadbfdc3SEiji Ota 	} else {
71cadbfdc3SEiji Ota 		transports[trans->t_type] = trans;
72cadbfdc3SEiji Ota 		RDSV3_DPRINTF2("rdsv3_trans_register",
73cadbfdc3SEiji Ota 		    "Registered RDS/%s transport\n", trans->t_name);
74cadbfdc3SEiji Ota 	}
75c0dd49bdSEiji Ota 
76c0dd49bdSEiji Ota 	rw_exit(&trans_sem);
77c0dd49bdSEiji Ota 
78c0dd49bdSEiji Ota 	RDSV3_DPRINTF4("rdsv3_trans_register", "Return(trans: %p)", trans);
79c0dd49bdSEiji Ota 
80c0dd49bdSEiji Ota 	return (0);
81c0dd49bdSEiji Ota }
82c0dd49bdSEiji Ota 
83c0dd49bdSEiji Ota void
rdsv3_trans_unregister(struct rdsv3_transport * trans)84c0dd49bdSEiji Ota rdsv3_trans_unregister(struct rdsv3_transport *trans)
85c0dd49bdSEiji Ota {
86c0dd49bdSEiji Ota 	RDSV3_DPRINTF4("rdsv3_trans_register", "Enter(trans: %p)", trans);
87c0dd49bdSEiji Ota 
88c0dd49bdSEiji Ota 	rw_enter(&trans_sem, RW_WRITER);
89c0dd49bdSEiji Ota 
90cadbfdc3SEiji Ota 	transports[trans->t_type] = NULL;
91c0dd49bdSEiji Ota 
92c0dd49bdSEiji Ota 	rw_exit(&trans_sem);
93c0dd49bdSEiji Ota 
94c0dd49bdSEiji Ota 	RDSV3_DPRINTF4("rdsv3_trans_register", "Return(trans: %p)", trans);
95c0dd49bdSEiji Ota }
96c0dd49bdSEiji Ota 
97c0dd49bdSEiji Ota struct rdsv3_transport *
rdsv3_trans_get_preferred(uint32_be_t addr)98c0dd49bdSEiji Ota rdsv3_trans_get_preferred(uint32_be_t addr)
99c0dd49bdSEiji Ota {
100c0dd49bdSEiji Ota 	struct rdsv3_transport *ret = NULL;
101cadbfdc3SEiji Ota 	int i;
102c0dd49bdSEiji Ota 
103c0dd49bdSEiji Ota 	RDSV3_DPRINTF4("rdsv3_trans_get_preferred", "Enter(addr: %x)",
104c0dd49bdSEiji Ota 	    ntohl(addr));
105c0dd49bdSEiji Ota 
106c0dd49bdSEiji Ota 	if (rdsv3_isloopback(addr))
107c0dd49bdSEiji Ota 		return (&rdsv3_loop_transport);
108c0dd49bdSEiji Ota 
109c0dd49bdSEiji Ota 	rw_enter(&trans_sem, RW_READER);
110cadbfdc3SEiji Ota 	for (i = 0; i < RDS_TRANS_COUNT; i++) {
1115d5562f5SEiji Ota 		if (transports[i] &&
1125d5562f5SEiji Ota 		    transports[i]->laddr_check(addr) == 0) {
113cadbfdc3SEiji Ota 			ret = transports[i];
114c0dd49bdSEiji Ota 			break;
115c0dd49bdSEiji Ota 		}
116c0dd49bdSEiji Ota 	}
117c0dd49bdSEiji Ota 	rw_exit(&trans_sem);
118c0dd49bdSEiji Ota 
119c0dd49bdSEiji Ota 	RDSV3_DPRINTF4("rdsv3_trans_get_preferred",
120c0dd49bdSEiji Ota 	    "Return(addr: %x, ret: %p)", ntohl(addr), ret);
121c0dd49bdSEiji Ota 
122c0dd49bdSEiji Ota 	return (ret);
123c0dd49bdSEiji Ota }
124c0dd49bdSEiji Ota 
125c0dd49bdSEiji Ota /*
126c0dd49bdSEiji Ota  * This returns the number of stats entries in the snapshot and only
127c0dd49bdSEiji Ota  * copies them using the iter if there is enough space for them.  The
128c0dd49bdSEiji Ota  * caller passes in the global stats so that we can size and copy while
129c0dd49bdSEiji Ota  * holding the lock.
130c0dd49bdSEiji Ota  */
131c0dd49bdSEiji Ota /* ARGSUSED */
132c0dd49bdSEiji Ota unsigned int
rdsv3_trans_stats_info_copy(struct rdsv3_info_iterator * iter,unsigned int avail)133c0dd49bdSEiji Ota rdsv3_trans_stats_info_copy(struct rdsv3_info_iterator *iter,
134c0dd49bdSEiji Ota     unsigned int avail)
135c0dd49bdSEiji Ota {
136*5e12ddadSEiji Ota 	struct rdsv3_transport *trans;
137*5e12ddadSEiji Ota 	unsigned int total = 0;
138*5e12ddadSEiji Ota 	unsigned int part;
139*5e12ddadSEiji Ota 	int i;
140*5e12ddadSEiji Ota 
141*5e12ddadSEiji Ota 	rw_enter(&trans_sem, RW_READER);
142*5e12ddadSEiji Ota 
143*5e12ddadSEiji Ota 	for (i = 0; i < RDS_TRANS_COUNT; i++) {
144*5e12ddadSEiji Ota 		trans = transports[i];
145*5e12ddadSEiji Ota 		if (!trans || !trans->stats_info_copy)
146*5e12ddadSEiji Ota 			continue;
147*5e12ddadSEiji Ota 
148*5e12ddadSEiji Ota 		part = trans->stats_info_copy(iter, avail);
149*5e12ddadSEiji Ota 		avail -= min(avail, part);
150*5e12ddadSEiji Ota 		total += part;
151*5e12ddadSEiji Ota 	}
152*5e12ddadSEiji Ota 
153*5e12ddadSEiji Ota 	rw_exit(&trans_sem);
154*5e12ddadSEiji Ota 
155*5e12ddadSEiji Ota 	return (total);
156c0dd49bdSEiji Ota }
157