1/* 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32#include <linux/module.h> 33#include <linux/moduleparam.h> 34 35#include <rdma/ib_verbs.h> 36 37#include "cxgb3_offload.h" 38#include "iwch_provider.h" 39#include "iwch_user.h" 40#include "iwch.h" 41#include "iwch_cm.h" 42 43#define DRV_VERSION "1.1" 44 45MODULE_AUTHOR("Boyd Faulkner, Steve Wise"); 46MODULE_DESCRIPTION("Chelsio T3 RDMA Driver"); 47MODULE_LICENSE("Dual BSD/GPL"); 48MODULE_VERSION(DRV_VERSION); 49 50cxgb3_cpl_handler_func t3c_handlers[NUM_CPL_CMDS]; 51 52static void open_rnic_dev(struct t3cdev *); 53static void close_rnic_dev(struct t3cdev *); 54 55struct cxgb3_client t3c_client = { 56 .name = "iw_cxgb3", 57 .add = open_rnic_dev, 58 .remove = close_rnic_dev, 59 .handlers = t3c_handlers, 60 .redirect = iwch_ep_redirect 61}; 62 63static LIST_HEAD(dev_list); 64static DEFINE_MUTEX(dev_mutex); 65 66static void rnic_init(struct iwch_dev *rnicp) 67{ 68 PDBG("%s iwch_dev %p\n", __FUNCTION__, rnicp); 69 idr_init(&rnicp->cqidr); 70 idr_init(&rnicp->qpidr); 71 idr_init(&rnicp->mmidr); 72 spin_lock_init(&rnicp->lock); 73 74 rnicp->attr.vendor_id = 0x168; 75 rnicp->attr.vendor_part_id = 7; 76 rnicp->attr.max_qps = T3_MAX_NUM_QP - 32; 77 rnicp->attr.max_wrs = (1UL << 24) - 1; 78 rnicp->attr.max_sge_per_wr = T3_MAX_SGE; 79 rnicp->attr.max_sge_per_rdma_write_wr = T3_MAX_SGE; 80 rnicp->attr.max_cqs = T3_MAX_NUM_CQ - 1; 81 rnicp->attr.max_cqes_per_cq = (1UL << 24) - 1; 82 rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev); 83 rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; 84 rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; 85 rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */ 86 rnicp->attr.can_resize_wq = 0; 87 rnicp->attr.max_rdma_reads_per_qp = 8; 88 rnicp->attr.max_rdma_read_resources = 89 rnicp->attr.max_rdma_reads_per_qp * rnicp->attr.max_qps; 90 rnicp->attr.max_rdma_read_qp_depth = 8; /* IRD */ 91 rnicp->attr.max_rdma_read_depth = 92 rnicp->attr.max_rdma_read_qp_depth * rnicp->attr.max_qps; 93 rnicp->attr.rq_overflow_handled = 0; 94 rnicp->attr.can_modify_ird = 0; 95 rnicp->attr.can_modify_ord = 0; 96 rnicp->attr.max_mem_windows = rnicp->attr.max_mem_regs - 1; 97 rnicp->attr.stag0_value = 1; 98 rnicp->attr.zbva_support = 1; 99 rnicp->attr.local_invalidate_fence = 1; 100 rnicp->attr.cq_overflow_detection = 1; 101 return; 102} 103 104static void open_rnic_dev(struct t3cdev *tdev) 105{ 106 struct iwch_dev *rnicp; 107 static int vers_printed; 108 109 PDBG("%s t3cdev %p\n", __FUNCTION__, tdev); 110 if (!vers_printed++) 111 printk(KERN_INFO MOD "Chelsio T3 RDMA Driver - version %s\n", 112 DRV_VERSION); 113 rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp)); 114 if (!rnicp) { 115 printk(KERN_ERR MOD "Cannot allocate ib device\n"); 116 return; 117 } 118 rnicp->rdev.ulp = rnicp; 119 rnicp->rdev.t3cdev_p = tdev; 120 121 mutex_lock(&dev_mutex); 122 123 if (cxio_rdev_open(&rnicp->rdev)) { 124 mutex_unlock(&dev_mutex); 125 printk(KERN_ERR MOD "Unable to open CXIO rdev\n"); 126 ib_dealloc_device(&rnicp->ibdev); 127 return; 128 } 129 130 rnic_init(rnicp); 131 132 list_add_tail(&rnicp->entry, &dev_list); 133 mutex_unlock(&dev_mutex); 134 135 if (iwch_register_device(rnicp)) { 136 printk(KERN_ERR MOD "Unable to register device\n"); 137 close_rnic_dev(tdev); 138 } 139 printk(KERN_INFO MOD "Initialized device %s\n", 140 pci_name(rnicp->rdev.rnic_info.pdev)); 141 return; 142} 143 144static void close_rnic_dev(struct t3cdev *tdev) 145{ 146 struct iwch_dev *dev, *tmp; 147 PDBG("%s t3cdev %p\n", __FUNCTION__, tdev); 148 mutex_lock(&dev_mutex); 149 list_for_each_entry_safe(dev, tmp, &dev_list, entry) { 150 if (dev->rdev.t3cdev_p == tdev) { 151 list_del(&dev->entry); 152 iwch_unregister_device(dev); 153 cxio_rdev_close(&dev->rdev); 154 idr_destroy(&dev->cqidr); 155 idr_destroy(&dev->qpidr); 156 idr_destroy(&dev->mmidr); 157 ib_dealloc_device(&dev->ibdev); 158 break; 159 } 160 } 161 mutex_unlock(&dev_mutex); 162} 163 164static int __init iwch_init_module(void) 165{ 166 int err; 167 168 err = cxio_hal_init(); 169 if (err) 170 return err; 171 err = iwch_cm_init(); 172 if (err) 173 return err; 174 cxio_register_ev_cb(iwch_ev_dispatch); 175 cxgb3_register_client(&t3c_client); 176 return 0; 177} 178 179static void __exit iwch_exit_module(void) 180{ 181 cxgb3_unregister_client(&t3c_client); 182 cxio_unregister_ev_cb(iwch_ev_dispatch); 183 iwch_cm_term(); 184 cxio_hal_exit(); 185} 186 187module_init(iwch_init_module); 188module_exit(iwch_exit_module); 189