Linux Audio

Check our new training course

Embedded Linux training

Mar 31-Apr 8, 2025
Register
Loading...
Note: File does not exist in v6.8.
  1/*
  2 *  IBM eServer eHCA Infiniband device driver for Linux on POWER
  3 *
  4 *  mcast  functions
  5 *
  6 *  Authors: Khadija Souissi <souissik@de.ibm.com>
  7 *           Waleri Fomin <fomin@de.ibm.com>
  8 *           Reinhard Ernst <rernst@de.ibm.com>
  9 *           Hoang-Nam Nguyen <hnguyen@de.ibm.com>
 10 *           Heiko J Schick <schickhj@de.ibm.com>
 11 *
 12 *  Copyright (c) 2005 IBM Corporation
 13 *
 14 *  All rights reserved.
 15 *
 16 *  This source code is distributed under a dual license of GPL v2.0 and OpenIB
 17 *  BSD.
 18 *
 19 * OpenIB BSD License
 20 *
 21 * Redistribution and use in source and binary forms, with or without
 22 * modification, are permitted provided that the following conditions are met:
 23 *
 24 * Redistributions of source code must retain the above copyright notice, this
 25 * list of conditions and the following disclaimer.
 26 *
 27 * Redistributions in binary form must reproduce the above copyright notice,
 28 * this list of conditions and the following disclaimer in the documentation
 29 * and/or other materials
 30 * provided with the distribution.
 31 *
 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 33 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 36 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 37 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 38 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 39 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 40 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 42 * POSSIBILITY OF SUCH DAMAGE.
 43 */
 44
 45#include <linux/module.h>
 46#include <linux/err.h>
 47#include "ehca_classes.h"
 48#include "ehca_tools.h"
 49#include "ehca_qes.h"
 50#include "ehca_iverbs.h"
 51#include "hcp_if.h"
 52
 53#define MAX_MC_LID 0xFFFE
 54#define MIN_MC_LID 0xC000	/* Multicast limits */
 55#define EHCA_VALID_MULTICAST_GID(gid)  ((gid)[0] == 0xFF)
 56#define EHCA_VALID_MULTICAST_LID(lid) \
 57	(((lid) >= MIN_MC_LID) && ((lid) <= MAX_MC_LID))
 58
 59int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 60{
 61	struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
 62	struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca,
 63					      ib_device);
 64	union ib_gid my_gid;
 65	u64 subnet_prefix, interface_id, h_ret;
 66
 67	if (ibqp->qp_type != IB_QPT_UD) {
 68		ehca_err(ibqp->device, "invalid qp_type=%x", ibqp->qp_type);
 69		return -EINVAL;
 70	}
 71
 72	if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) {
 73		ehca_err(ibqp->device, "invalid mulitcast gid");
 74		return -EINVAL;
 75	} else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) {
 76		ehca_err(ibqp->device, "invalid mulitcast lid=%x", lid);
 77		return -EINVAL;
 78	}
 79
 80	memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid));
 81
 82	subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
 83	interface_id = be64_to_cpu(my_gid.global.interface_id);
 84	h_ret = hipz_h_attach_mcqp(shca->ipz_hca_handle,
 85				   my_qp->ipz_qp_handle,
 86				   my_qp->galpas.kernel,
 87				   lid, subnet_prefix, interface_id);
 88	if (h_ret != H_SUCCESS)
 89		ehca_err(ibqp->device,
 90			 "ehca_qp=%p qp_num=%x hipz_h_attach_mcqp() failed "
 91			 "h_ret=%lli", my_qp, ibqp->qp_num, h_ret);
 92
 93	return ehca2ib_return_code(h_ret);
 94}
 95
 96int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 97{
 98	struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
 99	struct ehca_shca *shca = container_of(ibqp->pd->device,
100					      struct ehca_shca, ib_device);
101	union ib_gid my_gid;
102	u64 subnet_prefix, interface_id, h_ret;
103
104	if (ibqp->qp_type != IB_QPT_UD) {
105		ehca_err(ibqp->device, "invalid qp_type %x", ibqp->qp_type);
106		return -EINVAL;
107	}
108
109	if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) {
110		ehca_err(ibqp->device, "invalid mulitcast gid");
111		return -EINVAL;
112	} else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) {
113		ehca_err(ibqp->device, "invalid mulitcast lid=%x", lid);
114		return -EINVAL;
115	}
116
117	memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid));
118
119	subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
120	interface_id = be64_to_cpu(my_gid.global.interface_id);
121	h_ret = hipz_h_detach_mcqp(shca->ipz_hca_handle,
122				   my_qp->ipz_qp_handle,
123				   my_qp->galpas.kernel,
124				   lid, subnet_prefix, interface_id);
125	if (h_ret != H_SUCCESS)
126		ehca_err(ibqp->device,
127			 "ehca_qp=%p qp_num=%x hipz_h_detach_mcqp() failed "
128			 "h_ret=%lli", my_qp, ibqp->qp_num, h_ret);
129
130	return ehca2ib_return_code(h_ret);
131}