source: bootcd/isolinux/syslinux-6.03/gpxe/src/net/infiniband/ib_mcast.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*
2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19FILE_LICENCE ( GPL2_OR_LATER );
20
21#include <stdint.h>
22#include <string.h>
23#include <byteswap.h>
24#include <errno.h>
25#include <gpxe/list.h>
26#include <gpxe/infiniband.h>
27#include <gpxe/ib_mi.h>
28#include <gpxe/ib_mcast.h>
29
30/** @file
31 *
32 * Infiniband multicast groups
33 *
34 */
35
36/**
37 * Generate multicast membership MAD
38 *
39 * @v ibdev             Infiniband device
40 * @v gid               Multicast GID
41 * @v join              Join (rather than leave) group
42 * @v mad               MAD to fill in
43 */
44static void ib_mcast_mad ( struct ib_device *ibdev, struct ib_gid *gid,
45                           int join, union ib_mad *mad ) {
46        struct ib_mad_sa *sa = &mad->sa;
47
48        /* Construct multicast membership record request */
49        memset ( sa, 0, sizeof ( *sa ) );
50        sa->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
51        sa->mad_hdr.class_version = IB_SA_CLASS_VERSION;
52        sa->mad_hdr.method =
53                ( join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE );
54        sa->mad_hdr.attr_id = htons ( IB_SA_ATTR_MC_MEMBER_REC );
55        sa->sa_hdr.comp_mask[1] =
56                htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
57                        IB_SA_MCMEMBER_REC_JOIN_STATE );
58        sa->sa_data.mc_member_record.scope__join_state = 1;
59        memcpy ( &sa->sa_data.mc_member_record.mgid, gid,
60                 sizeof ( sa->sa_data.mc_member_record.mgid ) );
61        memcpy ( &sa->sa_data.mc_member_record.port_gid, &ibdev->gid,
62                 sizeof ( sa->sa_data.mc_member_record.port_gid ) );
63}
64
65/**
66 * Handle multicast membership record join response
67 *
68 * @v ibdev             Infiniband device
69 * @v mi                Management interface
70 * @v madx              Management transaction
71 * @v rc                Status code
72 * @v mad               Received MAD (or NULL on error)
73 * @v av                Source address vector (or NULL on error)
74 */
75static void ib_mcast_complete ( struct ib_device *ibdev,
76                                struct ib_mad_interface *mi __unused,
77                                struct ib_mad_transaction *madx,
78                                int rc, union ib_mad *mad,
79                                struct ib_address_vector *av __unused ) {
80        struct ib_mc_membership *membership = ib_madx_get_ownerdata ( madx );
81        struct ib_queue_pair *qp = membership->qp;
82        struct ib_gid *gid = &membership->gid;
83        struct ib_mc_member_record *mc_member_record =
84                &mad->sa.sa_data.mc_member_record;
85        int joined;
86        unsigned long qkey;
87
88        /* Report failures */
89        if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) ))
90                rc = -ENOTCONN;
91        if ( rc != 0 ) {
92                DBGC ( ibdev, "IBDEV %p QPN %lx join failed: %s\n",
93                       ibdev, qp->qpn, strerror ( rc ) );
94                goto out;
95        }
96
97        /* Extract values from MAD */
98        joined = ( mad->hdr.method == IB_MGMT_METHOD_GET_RESP );
99        qkey = ntohl ( mc_member_record->qkey );
100        DBGC ( ibdev, "IBDEV %p QPN %lx %s %08x:%08x:%08x:%08x qkey %lx\n",
101               ibdev, qp->qpn, ( joined ? "joined" : "left" ),
102               ntohl ( gid->u.dwords[0] ), ntohl ( gid->u.dwords[1] ),
103               ntohl ( gid->u.dwords[2] ), ntohl ( gid->u.dwords[3] ),
104               qkey );
105
106        /* Set queue key */
107        qp->qkey = qkey;
108        if ( ( rc = ib_modify_qp ( ibdev, qp ) ) != 0 ) {
109                DBGC ( ibdev, "IBDEV %p QPN %lx could not modify qkey: %s\n",
110                       ibdev, qp->qpn, strerror ( rc ) );
111                goto out;
112        }
113
114 out:
115        /* Destroy the completed transaction */
116        ib_destroy_madx ( ibdev, mi, madx );
117        membership->madx = NULL;
118
119        /* Hand off to upper completion handler */
120        membership->complete ( ibdev, qp, membership, rc, mad );
121}
122
123/** Multicast membership management transaction completion operations */
124static struct ib_mad_transaction_operations ib_mcast_op = {
125        .complete = ib_mcast_complete,
126};
127
128/**
129 * Join multicast group
130 *
131 * @v ibdev             Infiniband device
132 * @v qp                Queue pair
133 * @v membership        Multicast group membership
134 * @v gid               Multicast GID to join
135 * @v joined            Join completion handler
136 * @ret rc              Return status code
137 */
138int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
139                    struct ib_mc_membership *membership, struct ib_gid *gid,
140                    void ( * complete ) ( struct ib_device *ibdev,
141                                          struct ib_queue_pair *qp,
142                                          struct ib_mc_membership *membership,
143                                          int rc, union ib_mad *mad ) ) {
144        union ib_mad mad;
145        int rc;
146
147        DBGC ( ibdev, "IBDEV %p QPN %lx joining %08x:%08x:%08x:%08x\n",
148               ibdev, qp->qpn, ntohl ( gid->u.dwords[0] ),
149               ntohl ( gid->u.dwords[1] ), ntohl ( gid->u.dwords[2] ),
150               ntohl ( gid->u.dwords[3] ) );
151
152        /* Initialise structure */
153        membership->qp = qp;
154        memcpy ( &membership->gid, gid, sizeof ( membership->gid ) );
155        membership->complete = complete;
156
157        /* Attach queue pair to multicast GID */
158        if ( ( rc = ib_mcast_attach ( ibdev, qp, gid ) ) != 0 ) {
159                DBGC ( ibdev, "IBDEV %p QPN %lx could not attach: %s\n",
160                       ibdev, qp->qpn, strerror ( rc ) );
161                goto err_mcast_attach;
162        }
163
164        /* Initiate multicast membership join */
165        ib_mcast_mad ( ibdev, gid, 1, &mad );
166        membership->madx = ib_create_madx ( ibdev, ibdev->gsi, &mad, NULL,
167                                            &ib_mcast_op );
168        if ( ! membership->madx ) {
169                DBGC ( ibdev, "IBDEV %p QPN %lx could not create join "
170                       "transaction\n", ibdev, qp->qpn );
171                rc = -ENOMEM;
172                goto err_create_madx;
173        }
174        ib_madx_set_ownerdata ( membership->madx, membership );
175
176        return 0;
177
178        ib_destroy_madx ( ibdev, ibdev->gsi, membership->madx );
179 err_create_madx:
180        ib_mcast_detach ( ibdev, qp, gid );
181 err_mcast_attach:
182        return rc;
183}
184
185/**
186 * Leave multicast group
187 *
188 * @v ibdev             Infiniband device
189 * @v qp                Queue pair
190 * @v membership        Multicast group membership
191 */
192void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
193                      struct ib_mc_membership *membership ) {
194        struct ib_gid *gid = &membership->gid;
195        union ib_mad mad;
196        int rc;
197
198        DBGC ( ibdev, "IBDEV %p QPN %lx leaving %08x:%08x:%08x:%08x\n",
199               ibdev, qp->qpn, ntohl ( gid->u.dwords[0] ),
200               ntohl ( gid->u.dwords[1] ), ntohl ( gid->u.dwords[2] ),
201               ntohl ( gid->u.dwords[3] ) );
202
203        /* Detach from multicast GID */
204        ib_mcast_detach ( ibdev, qp, &membership->gid );
205
206        /* Cancel multicast membership join, if applicable */
207        if ( membership->madx ) {
208                ib_destroy_madx ( ibdev, ibdev->gsi, membership->madx );
209                membership->madx = NULL;
210        }
211
212        /* Send a single group leave MAD */
213        ib_mcast_mad ( ibdev, &membership->gid, 0, &mad );
214        if ( ( rc = ib_mi_send ( ibdev, ibdev->gsi, &mad, NULL ) ) != 0 ) {
215                DBGC ( ibdev, "IBDEV %p QPN %lx could not send leave request: "
216                       "%s\n", ibdev, qp->qpn, strerror ( rc ) );
217        }
218}
Note: See TracBrowser for help on using the repository browser.