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