|  | @@ -42,11 +42,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
		
	
		
			
			| 42 | 42 |   * Generate multicast membership MAD
 | 
		
	
		
			
			| 43 | 43 |   *
 | 
		
	
		
			
			| 44 | 44 |   * @v ibdev		Infiniband device
 | 
		
	
		
			
			| 45 |  | - * @v gid		Multicast GID
 | 
		
	
		
			
			|  | 45 | + * @v av		Address vector
 | 
		
	
		
			
			| 46 | 46 |   * @v join		Join (rather than leave) group
 | 
		
	
		
			
			| 47 | 47 |   * @v mad		MAD to fill in
 | 
		
	
		
			
			| 48 | 48 |   */
 | 
		
	
		
			
			| 49 |  | -static void ib_mcast_mad ( struct ib_device *ibdev, union ib_gid *gid,
 | 
		
	
		
			
			|  | 49 | +static void ib_mcast_mad ( struct ib_device *ibdev,
 | 
		
	
		
			
			|  | 50 | +			   struct ib_address_vector *av,
 | 
		
	
		
			
			| 50 | 51 |  			   int join, union ib_mad *mad ) {
 | 
		
	
		
			
			| 51 | 52 |  	struct ib_mad_sa *sa = &mad->sa;
 | 
		
	
		
			
			| 52 | 53 |  
 | 
		
	
	
		
			
			|  | @@ -61,7 +62,7 @@ static void ib_mcast_mad ( struct ib_device *ibdev, union ib_gid *gid,
 | 
		
	
		
			
			| 61 | 62 |  		htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
 | 
		
	
		
			
			| 62 | 63 |  			IB_SA_MCMEMBER_REC_JOIN_STATE );
 | 
		
	
		
			
			| 63 | 64 |  	sa->sa_data.mc_member_record.scope__join_state = 1;
 | 
		
	
		
			
			| 64 |  | -	memcpy ( &sa->sa_data.mc_member_record.mgid, gid,
 | 
		
	
		
			
			|  | 65 | +	memcpy ( &sa->sa_data.mc_member_record.mgid, &av->gid,
 | 
		
	
		
			
			| 65 | 66 |  		 sizeof ( sa->sa_data.mc_member_record.mgid ) );
 | 
		
	
		
			
			| 66 | 67 |  	memcpy ( &sa->sa_data.mc_member_record.port_gid, &ibdev->gid,
 | 
		
	
		
			
			| 67 | 68 |  		 sizeof ( sa->sa_data.mc_member_record.port_gid ) );
 | 
		
	
	
		
			
			|  | @@ -75,20 +76,19 @@ static void ib_mcast_mad ( struct ib_device *ibdev, union ib_gid *gid,
 | 
		
	
		
			
			| 75 | 76 |   * @v madx		Management transaction
 | 
		
	
		
			
			| 76 | 77 |   * @v rc		Status code
 | 
		
	
		
			
			| 77 | 78 |   * @v mad		Received MAD (or NULL on error)
 | 
		
	
		
			
			| 78 |  | - * @v av		Source address vector (or NULL on error)
 | 
		
	
		
			
			|  | 79 | + * @v src		Source address vector (or NULL on error)
 | 
		
	
		
			
			| 79 | 80 |   */
 | 
		
	
		
			
			| 80 | 81 |  static void ib_mcast_complete ( struct ib_device *ibdev,
 | 
		
	
		
			
			| 81 | 82 |  				struct ib_mad_interface *mi __unused,
 | 
		
	
		
			
			| 82 | 83 |  				struct ib_mad_transaction *madx,
 | 
		
	
		
			
			| 83 | 84 |  				int rc, union ib_mad *mad,
 | 
		
	
		
			
			| 84 |  | -				struct ib_address_vector *av __unused ) {
 | 
		
	
		
			
			|  | 85 | +				struct ib_address_vector *src __unused ) {
 | 
		
	
		
			
			| 85 | 86 |  	struct ib_mc_membership *membership = ib_madx_get_ownerdata ( madx );
 | 
		
	
		
			
			| 86 | 87 |  	struct ib_queue_pair *qp = membership->qp;
 | 
		
	
		
			
			| 87 |  | -	union ib_gid *gid = &membership->gid;
 | 
		
	
		
			
			|  | 88 | +	struct ib_address_vector *av = membership->av;
 | 
		
	
		
			
			| 88 | 89 |  	struct ib_mc_member_record *mc_member_record =
 | 
		
	
		
			
			| 89 | 90 |  		&mad->sa.sa_data.mc_member_record;
 | 
		
	
		
			
			| 90 | 91 |  	int joined;
 | 
		
	
		
			
			| 91 |  | -	unsigned long qkey;
 | 
		
	
		
			
			| 92 | 92 |  
 | 
		
	
		
			
			| 93 | 93 |  	/* Report failures */
 | 
		
	
		
			
			| 94 | 94 |  	if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) ))
 | 
		
	
	
		
			
			|  | @@ -101,13 +101,17 @@ static void ib_mcast_complete ( struct ib_device *ibdev,
 | 
		
	
		
			
			| 101 | 101 |  
 | 
		
	
		
			
			| 102 | 102 |  	/* Extract values from MAD */
 | 
		
	
		
			
			| 103 | 103 |  	joined = ( mad->hdr.method == IB_MGMT_METHOD_GET_RESP );
 | 
		
	
		
			
			| 104 |  | -	qkey = ntohl ( mc_member_record->qkey );
 | 
		
	
		
			
			| 105 |  | -	DBGC ( ibdev, "IBDEV %s QPN %#lx %s " IB_GID_FMT " qkey %lx\n",
 | 
		
	
		
			
			|  | 104 | +	av->qkey = ntohl ( mc_member_record->qkey );
 | 
		
	
		
			
			|  | 105 | +	av->lid = ntohs ( mc_member_record->mlid );
 | 
		
	
		
			
			|  | 106 | +	av->rate = ( mc_member_record->rate_selector__rate & 0x3f );
 | 
		
	
		
			
			|  | 107 | +	av->sl = ( ( ntohl ( mc_member_record->sl__flow_label__hop_limit )
 | 
		
	
		
			
			|  | 108 | +		     >> 28 ) & 0x0f );
 | 
		
	
		
			
			|  | 109 | +	DBGC ( ibdev, "IBDEV %s QPN %#lx %s " IB_GID_FMT " qkey %#lx\n",
 | 
		
	
		
			
			| 106 | 110 |  	       ibdev->name, qp->qpn, ( joined ? "joined" : "left" ),
 | 
		
	
		
			
			| 107 |  | -	       IB_GID_ARGS ( gid ), qkey );
 | 
		
	
		
			
			|  | 111 | +	       IB_GID_ARGS ( &av->gid ), av->qkey );
 | 
		
	
		
			
			| 108 | 112 |  
 | 
		
	
		
			
			| 109 | 113 |  	/* Set queue key */
 | 
		
	
		
			
			| 110 |  | -	qp->qkey = qkey;
 | 
		
	
		
			
			|  | 114 | +	qp->qkey = av->qkey;
 | 
		
	
		
			
			| 111 | 115 |  	if ( ( rc = ib_modify_qp ( ibdev, qp ) ) != 0 ) {
 | 
		
	
		
			
			| 112 | 116 |  		DBGC ( ibdev, "IBDEV %s QPN %#lx could not modify qkey: %s\n",
 | 
		
	
		
			
			| 113 | 117 |  		       ibdev->name, qp->qpn, strerror ( rc ) );
 | 
		
	
	
		
			
			|  | @@ -120,7 +124,7 @@ static void ib_mcast_complete ( struct ib_device *ibdev,
 | 
		
	
		
			
			| 120 | 124 |  	membership->madx = NULL;
 | 
		
	
		
			
			| 121 | 125 |  
 | 
		
	
		
			
			| 122 | 126 |  	/* Hand off to upper completion handler */
 | 
		
	
		
			
			| 123 |  | -	membership->complete ( ibdev, qp, membership, rc, mad );
 | 
		
	
		
			
			|  | 127 | +	membership->complete ( membership, rc );
 | 
		
	
		
			
			| 124 | 128 |  }
 | 
		
	
		
			
			| 125 | 129 |  
 | 
		
	
		
			
			| 126 | 130 |  /** Multicast membership management transaction completion operations */
 | 
		
	
	
		
			
			|  | @@ -134,21 +138,20 @@ static struct ib_mad_transaction_operations ib_mcast_op = {
 | 
		
	
		
			
			| 134 | 138 |   * @v ibdev		Infiniband device
 | 
		
	
		
			
			| 135 | 139 |   * @v qp		Queue pair
 | 
		
	
		
			
			| 136 | 140 |   * @v membership	Multicast group membership
 | 
		
	
		
			
			| 137 |  | - * @v gid		Multicast GID to join
 | 
		
	
		
			
			|  | 141 | + * @v av		Address vector to fill in
 | 
		
	
		
			
			| 138 | 142 |   * @v joined		Join completion handler
 | 
		
	
		
			
			| 139 | 143 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 140 | 144 |   */
 | 
		
	
		
			
			| 141 | 145 |  int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 142 |  | -		    struct ib_mc_membership *membership, union ib_gid *gid,
 | 
		
	
		
			
			| 143 |  | -		    void ( * complete ) ( struct ib_device *ibdev,
 | 
		
	
		
			
			| 144 |  | -					  struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 145 |  | -					  struct ib_mc_membership *membership,
 | 
		
	
		
			
			| 146 |  | -					  int rc, union ib_mad *mad ) ) {
 | 
		
	
		
			
			|  | 146 | +		    struct ib_mc_membership *membership,
 | 
		
	
		
			
			|  | 147 | +		    struct ib_address_vector *av,
 | 
		
	
		
			
			|  | 148 | +		    void ( * complete ) ( struct ib_mc_membership *membership,
 | 
		
	
		
			
			|  | 149 | +					  int rc ) ) {
 | 
		
	
		
			
			| 147 | 150 |  	union ib_mad mad;
 | 
		
	
		
			
			| 148 | 151 |  	int rc;
 | 
		
	
		
			
			| 149 | 152 |  
 | 
		
	
		
			
			| 150 | 153 |  	DBGC ( ibdev, "IBDEV %s QPN %#lx joining " IB_GID_FMT "\n",
 | 
		
	
		
			
			| 151 |  | -	       ibdev->name, qp->qpn, IB_GID_ARGS ( gid ) );
 | 
		
	
		
			
			|  | 154 | +	       ibdev->name, qp->qpn, IB_GID_ARGS ( &av->gid ) );
 | 
		
	
		
			
			| 152 | 155 |  
 | 
		
	
		
			
			| 153 | 156 |  	/* Sanity checks */
 | 
		
	
		
			
			| 154 | 157 |  	assert ( qp != NULL );
 | 
		
	
	
		
			
			|  | @@ -156,11 +159,11 @@ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 156 | 159 |  
 | 
		
	
		
			
			| 157 | 160 |  	/* Initialise structure */
 | 
		
	
		
			
			| 158 | 161 |  	membership->qp = qp;
 | 
		
	
		
			
			| 159 |  | -	memcpy ( &membership->gid, gid, sizeof ( membership->gid ) );
 | 
		
	
		
			
			|  | 162 | +	membership->av = av;
 | 
		
	
		
			
			| 160 | 163 |  	membership->complete = complete;
 | 
		
	
		
			
			| 161 | 164 |  
 | 
		
	
		
			
			| 162 | 165 |  	/* Attach queue pair to multicast GID */
 | 
		
	
		
			
			| 163 |  | -	if ( ( rc = ib_mcast_attach ( ibdev, qp, gid ) ) != 0 ) {
 | 
		
	
		
			
			|  | 166 | +	if ( ( rc = ib_mcast_attach ( ibdev, qp, &av->gid ) ) != 0 ) {
 | 
		
	
		
			
			| 164 | 167 |  		DBGC ( ibdev, "IBDEV %s QPN %#lx could not attach: %s\n",
 | 
		
	
		
			
			| 165 | 168 |  		       ibdev->name, qp->qpn, strerror ( rc ) );
 | 
		
	
		
			
			| 166 | 169 |  		goto err_mcast_attach;
 | 
		
	
	
		
			
			|  | @@ -168,7 +171,7 @@ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 168 | 171 |  	membership->attached = 1;
 | 
		
	
		
			
			| 169 | 172 |  
 | 
		
	
		
			
			| 170 | 173 |  	/* Initiate multicast membership join */
 | 
		
	
		
			
			| 171 |  | -	ib_mcast_mad ( ibdev, gid, 1, &mad );
 | 
		
	
		
			
			|  | 174 | +	ib_mcast_mad ( ibdev, av, 1, &mad );
 | 
		
	
		
			
			| 172 | 175 |  	membership->madx = ib_create_madx ( ibdev, ibdev->gsi, &mad, NULL,
 | 
		
	
		
			
			| 173 | 176 |  					    &ib_mcast_op );
 | 
		
	
		
			
			| 174 | 177 |  	if ( ! membership->madx ) {
 | 
		
	
	
		
			
			|  | @@ -183,7 +186,7 @@ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 183 | 186 |  
 | 
		
	
		
			
			| 184 | 187 |  	ib_destroy_madx ( ibdev, ibdev->gsi, membership->madx );
 | 
		
	
		
			
			| 185 | 188 |   err_create_madx:
 | 
		
	
		
			
			| 186 |  | -	ib_mcast_detach ( ibdev, qp, gid );
 | 
		
	
		
			
			|  | 189 | +	ib_mcast_detach ( ibdev, qp, &av->gid );
 | 
		
	
		
			
			| 187 | 190 |  	membership->attached = 0;
 | 
		
	
		
			
			| 188 | 191 |   err_mcast_attach:
 | 
		
	
		
			
			| 189 | 192 |  	return rc;
 | 
		
	
	
		
			
			|  | @@ -198,7 +201,7 @@ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 198 | 201 |   */
 | 
		
	
		
			
			| 199 | 202 |  void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 200 | 203 |  		      struct ib_mc_membership *membership ) {
 | 
		
	
		
			
			| 201 |  | -	union ib_gid *gid = &membership->gid;
 | 
		
	
		
			
			|  | 204 | +	struct ib_address_vector *av = membership->av;
 | 
		
	
		
			
			| 202 | 205 |  	union ib_mad mad;
 | 
		
	
		
			
			| 203 | 206 |  	int rc;
 | 
		
	
		
			
			| 204 | 207 |  
 | 
		
	
	
		
			
			|  | @@ -207,13 +210,13 @@ void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 207 | 210 |  		return;
 | 
		
	
		
			
			| 208 | 211 |  
 | 
		
	
		
			
			| 209 | 212 |  	DBGC ( ibdev, "IBDEV %s QPN %#lx leaving " IB_GID_FMT "\n",
 | 
		
	
		
			
			| 210 |  | -	       ibdev->name, qp->qpn, IB_GID_ARGS ( gid ) );
 | 
		
	
		
			
			|  | 213 | +	       ibdev->name, qp->qpn, IB_GID_ARGS ( &av->gid ) );
 | 
		
	
		
			
			| 211 | 214 |  
 | 
		
	
		
			
			| 212 | 215 |  	/* Sanity check */
 | 
		
	
		
			
			| 213 | 216 |  	assert ( qp != NULL );
 | 
		
	
		
			
			| 214 | 217 |  
 | 
		
	
		
			
			| 215 | 218 |  	/* Detach from multicast GID */
 | 
		
	
		
			
			| 216 |  | -	ib_mcast_detach ( ibdev, qp, &membership->gid );
 | 
		
	
		
			
			|  | 219 | +	ib_mcast_detach ( ibdev, qp, &av->gid );
 | 
		
	
		
			
			| 217 | 220 |  	membership->attached = 0;
 | 
		
	
		
			
			| 218 | 221 |  
 | 
		
	
		
			
			| 219 | 222 |  	/* Cancel multicast membership join, if applicable */
 | 
		
	
	
		
			
			|  | @@ -223,7 +226,7 @@ void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 223 | 226 |  	}
 | 
		
	
		
			
			| 224 | 227 |  
 | 
		
	
		
			
			| 225 | 228 |  	/* Send a single group leave MAD */
 | 
		
	
		
			
			| 226 |  | -	ib_mcast_mad ( ibdev, &membership->gid, 0, &mad );
 | 
		
	
		
			
			|  | 229 | +	ib_mcast_mad ( ibdev, av, 0, &mad );
 | 
		
	
		
			
			| 227 | 230 |  	if ( ( rc = ib_mi_send ( ibdev, ibdev->gsi, &mad, NULL ) ) != 0 ) {
 | 
		
	
		
			
			| 228 | 231 |  		DBGC ( ibdev, "IBDEV %s QPN %#lx could not send leave request: "
 | 
		
	
		
			
			| 229 | 232 |  		       "%s\n", ibdev->name, qp->qpn, strerror ( rc ) );
 |