c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * This file contains code imported from the OFED rds source file ib.c
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * Oracle elects to have and use the contents of ib.c under and governed
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * by the OpenIB.org BSD license (see below for full license text). However,
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * the following notice accompanied the original version of this file:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Copyright (c) 2006 Oracle. All rights reserved.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * This software is available to you under a choice of one of two
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * licenses. You may choose to be licensed under the terms of the GNU
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * General Public License (GPL) Version 2, available from the file
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * COPYING in the main directory of this source tree, or the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * OpenIB.org BSD license below:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Redistribution and use in source and binary forms, with or
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * without modification, are permitted provided that the following
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * conditions are met:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * - Redistributions of source code must retain the above
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * copyright notice, this list of conditions and the following
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * disclaimer.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * - Redistributions in binary form must reproduce the above
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * copyright notice, this list of conditions and the following
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * disclaimer in the documentation and/or other materials
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * provided with the distribution.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * SOFTWARE.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/sysmacros.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/rds.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/ibtl/ibti.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/clients/rdsv3/rdsv3.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/clients/rdsv3/ib.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/clients/rdsv3/rdsv3_debug.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaunsigned int rdsv3_ib_retry_count = RDSV3_IB_DEFAULT_RETRY_COUNT;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastruct list rdsv3_ib_devices;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* NOTE: if also grabbing ibdev lock, grab this first */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otakmutex_t ib_nodev_conns_lock;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otalist_t ib_nodev_conns;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
d2b539e744e90927cf7a57df3475145c279d68f9agiriextern int rdsv3_ib_frag_constructor(void *buf, void *arg, int kmflags);
d2b539e744e90927cf7a57df3475145c279d68f9agiriextern void rdsv3_ib_frag_destructor(void *buf, void *arg);
d2b539e744e90927cf7a57df3475145c279d68f9agiri
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_ib_add_one(ib_device_t *device)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdsv3_ib_device *rds_ibdev;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ibt_hca_attr_t *dev_attr;
d2b539e744e90927cf7a57df3475145c279d68f9agiri char name[64];
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
b27516f55237249607f754e6e42e865f12456675agiri RDSV3_DPRINTF2("rdsv3_ib_add_one", "device: %p", device);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* Only handle IB (no iWARP) devices */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (device->node_type != RDMA_NODE_IB_CA)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota dev_attr = (ibt_hca_attr_t *)kmem_alloc(sizeof (*dev_attr),
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KM_NOSLEEP);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (!dev_attr)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ibt_query_hca(ib_get_ibt_hca_hdl(device), dev_attr)) {
d2b539e744e90927cf7a57df3475145c279d68f9agiri RDSV3_DPRINTF2("rdsv3_ib_add_one",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "Query device failed for %s", device->name);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto free_attr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* We depend on Reserved Lkey */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (!(dev_attr->hca_flags2 & IBT_HCA2_RES_LKEY)) {
d2b539e744e90927cf7a57df3475145c279d68f9agiri RDSV3_DPRINTF2("rdsv3_ib_add_one",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "Reserved Lkey support is required: %s",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota device->name);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto free_attr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rds_ibdev = kmem_zalloc(sizeof (*rds_ibdev), KM_NOSLEEP);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (!rds_ibdev)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto free_attr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rds_ibdev->ibt_hca_hdl = ib_get_ibt_hca_hdl(device);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rds_ibdev->hca_attr = *dev_attr;
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rw_init(&rds_ibdev->rwlock, NULL, RW_DRIVER, NULL);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_init(&rds_ibdev->spinlock, NULL, MUTEX_DRIVER, NULL);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rds_ibdev->max_wrs = dev_attr->hca_max_chan_sz;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rds_ibdev->max_sge = min(dev_attr->hca_max_sgl, RDSV3_IB_MAX_SGE);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rds_ibdev->max_initiator_depth = (uint_t)dev_attr->hca_max_rdma_in_qp;
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rds_ibdev->max_responder_resources =
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota (uint_t)dev_attr->hca_max_rdma_in_qp;
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rds_ibdev->dev = device;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rds_ibdev->pd = ib_alloc_pd(device);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (IS_ERR(rds_ibdev->pd))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto free_dev;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_ib_create_mr_pool(rds_ibdev) != 0) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto free_dev;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota if (rdsv3_ib_create_inc_pool(rds_ibdev) != 0) {
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_ib_destroy_mr_pool(rds_ibdev);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota goto free_dev;
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota }
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota
d2b539e744e90927cf7a57df3475145c279d68f9agiri (void) snprintf(name, 64, "RDSV3_IB_FRAG_%llx",
d2b539e744e90927cf7a57df3475145c279d68f9agiri (longlong_t)htonll(dev_attr->hca_node_guid));
d2b539e744e90927cf7a57df3475145c279d68f9agiri rds_ibdev->ib_frag_slab = kmem_cache_create(name,
d2b539e744e90927cf7a57df3475145c279d68f9agiri sizeof (struct rdsv3_page_frag), 0, rdsv3_ib_frag_constructor,
d2b539e744e90927cf7a57df3475145c279d68f9agiri rdsv3_ib_frag_destructor, NULL, (void *)rds_ibdev, NULL, 0);
d2b539e744e90927cf7a57df3475145c279d68f9agiri if (rds_ibdev->ib_frag_slab == NULL) {
d2b539e744e90927cf7a57df3475145c279d68f9agiri RDSV3_DPRINTF2("rdsv3_ib_add_one",
d2b539e744e90927cf7a57df3475145c279d68f9agiri "kmem_cache_create for ib_frag_slab failed for device: %s",
d2b539e744e90927cf7a57df3475145c279d68f9agiri device->name);
d2b539e744e90927cf7a57df3475145c279d68f9agiri rdsv3_ib_destroy_mr_pool(rds_ibdev);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_ib_destroy_inc_pool(rds_ibdev);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota goto free_dev;
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota }
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rds_ibdev->aft_hcagp = rdsv3_af_grp_create(rds_ibdev->ibt_hca_hdl,
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota (uint64_t)rds_ibdev->hca_attr.hca_node_guid);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota if (rds_ibdev->aft_hcagp == NULL) {
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_ib_destroy_mr_pool(rds_ibdev);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_ib_destroy_inc_pool(rds_ibdev);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota kmem_cache_destroy(rds_ibdev->ib_frag_slab);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota goto free_dev;
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota }
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rds_ibdev->fmr_soft_cq = rdsv3_af_thr_create(rdsv3_ib_drain_mrlist_fn,
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota (void *)rds_ibdev->fmr_pool, SCQ_HCA_BIND_CPU,
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rds_ibdev->aft_hcagp);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota if (rds_ibdev->fmr_soft_cq == NULL) {
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_af_grp_destroy(rds_ibdev->aft_hcagp);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_ib_destroy_mr_pool(rds_ibdev);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_ib_destroy_inc_pool(rds_ibdev);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota kmem_cache_destroy(rds_ibdev->ib_frag_slab);
d2b539e744e90927cf7a57df3475145c279d68f9agiri goto free_dev;
d2b539e744e90927cf7a57df3475145c279d68f9agiri }
d2b539e744e90927cf7a57df3475145c279d68f9agiri
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rds_ibdev->inc_soft_cq = rdsv3_af_thr_create(rdsv3_ib_drain_inclist,
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota (void *)rds_ibdev->inc_pool, SCQ_HCA_BIND_CPU,
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rds_ibdev->aft_hcagp);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota if (rds_ibdev->inc_soft_cq == NULL) {
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_af_thr_destroy(rds_ibdev->fmr_soft_cq);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_af_grp_destroy(rds_ibdev->aft_hcagp);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_ib_destroy_mr_pool(rds_ibdev);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_ib_destroy_inc_pool(rds_ibdev);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota kmem_cache_destroy(rds_ibdev->ib_frag_slab);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota goto free_dev;
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota }
d2b539e744e90927cf7a57df3475145c279d68f9agiri
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_create(&rds_ibdev->ipaddr_list, sizeof (struct rdsv3_ib_ipaddr),
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota offsetof(struct rdsv3_ib_ipaddr, list));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_create(&rds_ibdev->conn_list, sizeof (struct rdsv3_ib_connection),
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota offsetof(struct rdsv3_ib_connection, ib_node));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_insert_tail(&rdsv3_ib_devices, rds_ibdev);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ib_set_client_data(device, &rdsv3_ib_client, rds_ibdev);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
b27516f55237249607f754e6e42e865f12456675agiri RDSV3_DPRINTF2("rdsv3_ib_add_one", "Return: device: %p", device);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto free_attr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaerr_pd:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (void) ib_dealloc_pd(rds_ibdev->pd);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otafree_dev:
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota mutex_destroy(&rds_ibdev->spinlock);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rw_destroy(&rds_ibdev->rwlock);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota kmem_free(rds_ibdev, sizeof (*rds_ibdev));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otafree_attr:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota kmem_free(dev_attr, sizeof (*dev_attr));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_ib_remove_one(struct ib_device *device)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdsv3_ib_device *rds_ibdev;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdsv3_ib_ipaddr *i_ipaddr, *i_next;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
b27516f55237249607f754e6e42e865f12456675agiri RDSV3_DPRINTF2("rdsv3_ib_remove_one", "device: %p", device);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rds_ibdev = ib_get_client_data(device, &rdsv3_ib_client);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (!rds_ibdev)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_FOR_EACH_LIST_NODE_SAFE(i_ipaddr, i_next, &rds_ibdev->ipaddr_list,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_remove_node(&i_ipaddr->list);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota kmem_free(i_ipaddr, sizeof (*i_ipaddr));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_destroy_conns(rds_ibdev);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota if (rds_ibdev->fmr_soft_cq)
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_af_thr_destroy(rds_ibdev->fmr_soft_cq);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota if (rds_ibdev->inc_soft_cq)
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_af_thr_destroy(rds_ibdev->inc_soft_cq);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_destroy_mr_pool(rds_ibdev);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_ib_destroy_inc_pool(rds_ibdev);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
d2b539e744e90927cf7a57df3475145c279d68f9agiri kmem_cache_destroy(rds_ibdev->ib_frag_slab);
d2b539e744e90927cf7a57df3475145c279d68f9agiri
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rdsv3_af_grp_destroy(rds_ibdev->aft_hcagp);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#if 0
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota while (ib_dealloc_pd(rds_ibdev->pd)) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#ifndef __lock_lint
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF5("rdsv3_ib_remove_one",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "%s-%d Failed to dealloc pd %p",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota __func__, __LINE__, rds_ibdev->pd);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota delay(drv_usectohz(1000));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#else
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ib_dealloc_pd(rds_ibdev->pd)) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#ifndef __lock_lint
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_ib_remove_one",
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota "Failed to dealloc pd %p\n", rds_ibdev->pd);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_destroy(&rds_ibdev->ipaddr_list);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_destroy(&rds_ibdev->conn_list);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_remove_node(&rds_ibdev->list);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota mutex_destroy(&rds_ibdev->spinlock);
5d5562f583b2b6affe19bdce0b3c8b1840d667a4Eiji Ota rw_destroy(&rds_ibdev->rwlock);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota kmem_free(rds_ibdev, sizeof (*rds_ibdev));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
b27516f55237249607f754e6e42e865f12456675agiri RDSV3_DPRINTF2("rdsv3_ib_remove_one", "Return: device: %p", device);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#ifndef __lock_lint
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastruct ib_client rdsv3_ib_client = {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .name = "rdsv3_ib",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .add = rdsv3_ib_add_one,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .remove = rdsv3_ib_remove_one,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .clnt_hdl = NULL,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .state = IB_CLNT_UNINITIALIZED
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota};
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#else
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastruct ib_client rdsv3_ib_client = {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "rdsv3_ib",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_add_one,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_remove_one,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota NULL,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota NULL,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota IB_CLNT_UNINITIALIZED
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota};
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic int
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otards_ib_conn_info_visitor(struct rdsv3_connection *conn,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota void *buffer)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
fe817b6022080da0a98b5d2d8cd179f594d6ca5eEiji Ota struct rds_info_rdma_connection *iinfo = buffer;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdsv3_ib_connection *ic;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF4("rds_ib_conn_info_visitor", "conn: %p buffer: %p",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota conn, buffer);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* We will only ever look at IB transports */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (conn->c_trans != &rdsv3_ib_transport)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return (0);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota iinfo->src_addr = conn->c_laddr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota iinfo->dst_addr = conn->c_faddr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (void) memset(&iinfo->src_gid, 0, sizeof (iinfo->src_gid));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (void) memset(&iinfo->dst_gid, 0, sizeof (iinfo->dst_gid));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_conn_state(conn) == RDSV3_CONN_UP) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdsv3_ib_device *rds_ibdev;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdma_dev_addr *dev_addr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ic = conn->c_transport_data;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota dev_addr = &ic->i_cm_id->route.addr.dev_addr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ib_addr_get_sgid(dev_addr, (union ib_gid *)&iinfo->src_gid);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ib_addr_get_dgid(dev_addr, (union ib_gid *)&iinfo->dst_gid);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rds_ibdev = ib_get_client_data(ic->i_cm_id->device,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota &rdsv3_ib_client);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota iinfo->max_send_wr = ic->i_send_ring.w_nr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota iinfo->max_recv_wr = ic->i_recv_ring.w_nr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota iinfo->max_send_sge = rds_ibdev->max_sge;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF4("rds_ib_conn_info_visitor", "conn: %p buffer: %p",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota conn, buffer);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return (1);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic void
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otards_ib_ic_info(struct rsock *sock, unsigned int len,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdsv3_info_iterator *iter,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdsv3_info_lengths *lens)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF4("rds_ib_ic_info", "sk: %p iter: %p, lens: %p, len: %d",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota sock, iter, lens, len);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_for_each_conn_info(sock, len, iter, lens,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rds_ib_conn_info_visitor,
fe817b6022080da0a98b5d2d8cd179f594d6ca5eEiji Ota sizeof (struct rds_info_rdma_connection));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Early RDS/IB was built to only bind to an address if there is an IPoIB
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * device with that address set.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * If it were me, I'd advocate for something more flexible. Sending and
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * receiving should be device-agnostic. Transports would try and maintain
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * connections between peers who have messages queued. Userspace would be
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * allowed to influence which paths have priority. We could call userspace
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * asserting this policy "routing".
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic int
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otards_ib_laddr_check(uint32_be_t addr)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota int ret;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdma_cm_id *cm_id;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct sockaddr_in sin;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF4("rds_ib_laddr_check", "addr: %x", ntohl(addr));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Create a CMA ID and try to bind it. This catches both
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * IB and iWARP capable NICs.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP);
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota if (!cm_id)
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota return (-EADDRNOTAVAIL);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (void) memset(&sin, 0, sizeof (sin));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota sin.sin_family = AF_INET;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota sin.sin_addr.s_addr = rdsv3_scaddr_to_ibaddr(addr);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* rdma_bind_addr will only succeed for IB & iWARP devices */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * due to this, we will claim to support iWARP devices unless we
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * check node_type.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ret || cm_id->device->node_type != RDMA_NODE_IB_CA)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = -EADDRNOTAVAIL;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF5("rds_ib_laddr_check",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "addr %u.%u.%u.%u ret %d node type %d",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota NIPQUAD(addr), ret,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cm_id->device ? cm_id->device->node_type : -1);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdma_destroy_id(cm_id);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return (ret);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_ib_exit(void)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF4("rds_ib_exit", "Enter");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
fe817b6022080da0a98b5d2d8cd179f594d6ca5eEiji Ota rdsv3_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_destroy_nodev_conns();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ib_unregister_client(&rdsv3_ib_client);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_sysctl_exit();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_recv_exit();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_trans_unregister(&rdsv3_ib_transport);
a530e0a9c7875fde3c123c906ca193a70dfacc4fagiri kmem_free(rdsv3_ib_stats,
a530e0a9c7875fde3c123c906ca193a70dfacc4fagiri nr_cpus * sizeof (struct rdsv3_ib_statistics));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_destroy(&ib_nodev_conns_lock);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_destroy(&ib_nodev_conns);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_destroy(&rdsv3_ib_devices);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF4("rds_ib_exit", "Return");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#ifndef __lock_lint
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastruct rdsv3_transport rdsv3_ib_transport = {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .laddr_check = rds_ib_laddr_check,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .xmit_complete = rdsv3_ib_xmit_complete,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .xmit = rdsv3_ib_xmit,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .xmit_cong_map = NULL,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .xmit_rdma = rdsv3_ib_xmit_rdma,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .recv = rdsv3_ib_recv,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .conn_alloc = rdsv3_ib_conn_alloc,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .conn_free = rdsv3_ib_conn_free,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .conn_connect = rdsv3_ib_conn_connect,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .conn_shutdown = rdsv3_ib_conn_shutdown,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .inc_copy_to_user = rdsv3_ib_inc_copy_to_user,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .inc_free = rdsv3_ib_inc_free,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .cm_initiate_connect = rdsv3_ib_cm_initiate_connect,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .cm_handle_connect = rdsv3_ib_cm_handle_connect,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .cm_connect_complete = rdsv3_ib_cm_connect_complete,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .stats_info_copy = rdsv3_ib_stats_info_copy,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .exit = rdsv3_ib_exit,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .get_mr = rdsv3_ib_get_mr,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .sync_mr = rdsv3_ib_sync_mr,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .free_mr = rdsv3_ib_free_mr,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .flush_mrs = rdsv3_ib_flush_mrs,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota .t_name = "infiniband",
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota .t_type = RDS_TRANS_IB
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota};
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#else
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastruct rdsv3_transport rdsv3_ib_transport;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaint
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_ib_init(void)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota int ret;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF4("rds_ib_init", "Enter");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_create(&rdsv3_ib_devices, sizeof (struct rdsv3_ib_device),
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota offsetof(struct rdsv3_ib_device, list));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_create(&ib_nodev_conns, sizeof (struct rdsv3_ib_connection),
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota offsetof(struct rdsv3_ib_connection, ib_node));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_init(&ib_nodev_conns_lock, NULL, MUTEX_DRIVER, NULL);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
a530e0a9c7875fde3c123c906ca193a70dfacc4fagiri /* allocate space for ib statistics */
a530e0a9c7875fde3c123c906ca193a70dfacc4fagiri ASSERT(rdsv3_ib_stats == NULL);
a530e0a9c7875fde3c123c906ca193a70dfacc4fagiri rdsv3_ib_stats = kmem_zalloc(nr_cpus *
a530e0a9c7875fde3c123c906ca193a70dfacc4fagiri sizeof (struct rdsv3_ib_statistics), KM_SLEEP);
a530e0a9c7875fde3c123c906ca193a70dfacc4fagiri
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_client.dip = rdsv3_dev_info;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = ib_register_client(&rdsv3_ib_client);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ret)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto out;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = rdsv3_ib_sysctl_init();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ret)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto out_ibreg;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = rdsv3_ib_recv_init();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ret)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto out_sysctl;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = rdsv3_trans_register(&rdsv3_ib_transport);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ret)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto out_recv;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
fe817b6022080da0a98b5d2d8cd179f594d6ca5eEiji Ota rdsv3_info_register_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF4("rds_ib_init", "Return");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return (0);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaout_recv:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_recv_exit();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaout_sysctl:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_sysctl_exit();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaout_ibreg:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ib_unregister_client(&rdsv3_ib_client);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaout:
a530e0a9c7875fde3c123c906ca193a70dfacc4fagiri kmem_free(rdsv3_ib_stats,
a530e0a9c7875fde3c123c906ca193a70dfacc4fagiri nr_cpus * sizeof (struct rdsv3_ib_statistics));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_destroy(&ib_nodev_conns_lock);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_destroy(&ib_nodev_conns);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_destroy(&rdsv3_ib_devices);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return (ret);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}