From mboxrd@z Thu Jan 1 00:00:00 1970 From: Adit Ranadive Subject: [PATCH 5/8] libpvrdma: Add misc verbs functions Date: Thu, 3 Nov 2016 16:44:34 -0700 Message-ID: <1478216677-6150-6-git-send-email-aditr@vmware.com> References: <1478216677-6150-1-git-send-email-aditr@vmware.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: In-Reply-To: <1478216677-6150-1-git-send-email-aditr-pghWNbHTmq7QT0dZR+AlfA@public.gmane.org> Sender: linux-rdma-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org, linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, pv-drivers-pghWNbHTmq7QT0dZR+AlfA@public.gmane.org Cc: Adit Ranadive List-Id: linux-rdma@vger.kernel.org This includes other verbs functions that dont necessarily fit anywhere else. Signed-off-by: Adit Ranadive --- providers/pvrdma/verbs.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 providers/pvrdma/verbs.c diff --git a/providers/pvrdma/verbs.c b/providers/pvrdma/verbs.c new file mode 100644 index 0000000..1646708 --- /dev/null +++ b/providers/pvrdma/verbs.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2012-2016 VMware, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of EITHER the GNU General Public License + * version 2 as published by the Free Software Foundation or the BSD + * 2-Clause License. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License version 2 for more details at + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html. + * + * You should have received a copy of the GNU General Public License + * along with this program available in the file COPYING in the main + * directory of this source tree. + * + * The BSD 2-Clause License + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pvrdma.h" + +int pvrdma_query_device(struct ibv_context *context, + struct ibv_device_attr *attr) +{ + struct ibv_query_device cmd; + uint64_t raw_fw_ver; + unsigned major, minor, sub_minor; + int ret; + + ret = ibv_cmd_query_device(context, attr, &raw_fw_ver, + &cmd, sizeof(cmd)); + if (ret) + return ret; + + major = (raw_fw_ver >> 32) & 0xffff; + minor = (raw_fw_ver >> 16) & 0xffff; + sub_minor = raw_fw_ver & 0xffff; + + snprintf(attr->fw_ver, sizeof(attr->fw_ver), + "%d.%d.%03d", major, minor, sub_minor); + + return 0; +} + +int pvrdma_query_port(struct ibv_context *context, uint8_t port, + struct ibv_port_attr *attr) +{ + struct ibv_query_port cmd; + + return ibv_cmd_query_port(context, port, attr, &cmd, sizeof(cmd)); +} + +struct ibv_pd *pvrdma_alloc_pd(struct ibv_context *context) +{ + struct ibv_alloc_pd cmd; + struct pvrdma_alloc_pd_resp resp; + struct pvrdma_pd *pd; + + pd = malloc(sizeof(*pd)); + if (!pd) + return NULL; + + if (ibv_cmd_alloc_pd(context, &pd->ibv_pd, &cmd, sizeof(cmd), + &resp.ibv_resp, sizeof(resp))) { + free(pd); + return NULL; + } + + pd->pdn = resp.pdn; + + return &pd->ibv_pd; +} + +int pvrdma_free_pd(struct ibv_pd *pd) +{ + int ret; + + ret = ibv_cmd_dealloc_pd(pd); + if (ret) + return ret; + + free(to_vpd(pd)); + + return 0; +} + +struct ibv_mr *pvrdma_reg_mr(struct ibv_pd *pd, void *addr, size_t length, + int access) +{ + struct ibv_mr *mr; + struct ibv_reg_mr cmd; + struct ibv_reg_mr_resp resp; + int ret; + + mr = malloc(sizeof(*mr)); + if (!mr) + return NULL; + + ret = ibv_cmd_reg_mr(pd, addr, length, (uintptr_t) addr, + access, mr, &cmd, sizeof(cmd), + &resp, sizeof(resp)); + if (ret) { + free(mr); + return NULL; + } + + return mr; +} + +int pvrdma_dereg_mr(struct ibv_mr *mr) +{ + int ret; + + ret = ibv_cmd_dereg_mr(mr); + if (ret) + return ret; + + free(mr); + + return 0; +} + +static int is_multicast_gid(const union ibv_gid *gid) +{ + return gid->raw[0] == 0xff; +} + +static int is_link_local_gid(const union ibv_gid *gid) +{ + uint32_t *hi = (uint32_t *)(gid->raw); + uint32_t *lo = (uint32_t *)(gid->raw + 4); + if (hi[0] == htonl(0xfe800000) && lo[0] == 0) + return 1; + + return 0; +} + +static int is_ipv6_addr_v4mapped(const struct in6_addr *a) +{ + return ((a->s6_addr32[0] | a->s6_addr32[1]) | + (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL || + /* IPv4 encoded multicast addresses */ + (a->s6_addr32[0] == htonl(0xff0e0000) && + ((a->s6_addr32[1] | + (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL)); +} + +static void set_mac_from_gid(const union ibv_gid *gid, + __u8 mac[6]) +{ + if (is_link_local_gid(gid)) { + /* + * The MAC is embedded in GID[8-10,13-15] with the + * 7th most significant bit inverted. + */ + memcpy(mac, gid->raw + 8, 3); + memcpy(mac + 3, gid->raw + 13, 3); + mac[0] ^= 2; + } +} + +struct ibv_ah *pvrdma_create_ah(struct ibv_pd *pd, + struct ibv_ah_attr *attr) +{ + struct pvrdma_ah *ah; + struct pvrdma_av *av; + struct ibv_port_attr port_attr; + + if (!attr->is_global) + return NULL; + + if (ibv_query_port(pd->context, attr->port_num, &port_attr)) + return NULL; + + if (port_attr.link_layer == IBV_LINK_LAYER_UNSPECIFIED || + port_attr.link_layer == IBV_LINK_LAYER_INFINIBAND) + return NULL; + + if (port_attr.link_layer == IBV_LINK_LAYER_ETHERNET && + (!is_link_local_gid(&attr->grh.dgid) && + !is_multicast_gid(&attr->grh.dgid) && + !is_ipv6_addr_v4mapped((struct in6_addr *)attr->grh.dgid.raw))) + return NULL; + + ah = calloc(1, sizeof(*ah)); + if (!ah) + return NULL; + + av = &ah->av; + av->port_pd = to_vpd(pd)->pdn | (attr->port_num << 24); + av->src_path_bits = attr->src_path_bits; + av->src_path_bits |= 0x80; + av->gid_index = attr->grh.sgid_index; + av->hop_limit = attr->grh.hop_limit; + av->sl_tclass_flowlabel = (attr->grh.traffic_class << 20) | + attr->grh.flow_label; + memcpy(av->dgid, attr->grh.dgid.raw, 16); + set_mac_from_gid(&attr->grh.dgid, av->dmac); + + return &ah->ibv_ah; +} + +int pvrdma_destroy_ah(struct ibv_ah *ah) +{ + free(to_vah(ah)); + + return 0; +} -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html