iw_cxgb.c revision 183289
1/************************************************************************** 2 3Copyright (c) 2007, Chelsio Inc. 4All rights reserved. 5 6Redistribution and use in source and binary forms, with or without 7modification, are permitted provided that the following conditions are met: 8 9 1. Redistributions of source code must retain the above copyright notice, 10 this list of conditions and the following disclaimer. 11 12 2. Neither the name of the Chelsio Corporation nor the names of its 13 contributors may be used to endorse or promote products derived from 14 this software without specific prior written permission. 15 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26POSSIBILITY OF SUCH DAMAGE. 27 28***************************************************************************/ 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: head/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb.c 183289 2008-09-23 02:22:24Z kmacy $"); 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/kernel.h> 35#include <sys/bus.h> 36#include <sys/module.h> 37#include <sys/pciio.h> 38#include <sys/conf.h> 39#include <machine/bus.h> 40#include <machine/resource.h> 41#include <sys/bus_dma.h> 42#include <sys/rman.h> 43#include <sys/ioccom.h> 44#include <sys/mbuf.h> 45#include <sys/rwlock.h> 46#include <sys/linker.h> 47#include <sys/firmware.h> 48#include <sys/socket.h> 49#include <sys/sockio.h> 50#include <sys/smp.h> 51#include <sys/sysctl.h> 52#include <sys/queue.h> 53#include <sys/taskqueue.h> 54#include <sys/proc.h> 55#include <sys/eventhandler.h> 56 57#if __FreeBSD_version >= 800044 58#include <sys/vimage.h> 59#else 60#define V_ifnet ifnet 61#endif 62 63#include <net/if.h> 64#include <net/if_var.h> 65 66#include <netinet/in.h> 67 68#include <contrib/rdma/ib_verbs.h> 69 70 71#ifdef CONFIG_DEFINED 72#include <cxgb_include.h> 73#include <ulp/iw_cxgb/iw_cxgb_wr.h> 74#include <ulp/iw_cxgb/iw_cxgb_hal.h> 75#include <ulp/iw_cxgb/iw_cxgb_provider.h> 76#include <ulp/iw_cxgb/iw_cxgb_cm.h> 77#include <ulp/iw_cxgb/iw_cxgb.h> 78#else 79#include <dev/cxgb/cxgb_include.h> 80#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_wr.h> 81#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_hal.h> 82#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_provider.h> 83#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.h> 84#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb.h> 85#endif 86 87/* 88 * XXX :-/ 89 * 90 */ 91 92#define idr_init(x) 93 94cxgb_cpl_handler_func t3c_handlers[NUM_CPL_CMDS]; 95 96static void open_rnic_dev(struct t3cdev *); 97static void close_rnic_dev(struct t3cdev *); 98 99static TAILQ_HEAD( ,iwch_dev) dev_list; 100static struct mtx dev_mutex; 101static eventhandler_tag event_tag; 102 103static void 104rnic_init(struct iwch_dev *rnicp) 105{ 106 CTR2(KTR_IW_CXGB, "%s iwch_dev %p", __FUNCTION__, rnicp); 107 idr_init(&rnicp->cqidr); 108 idr_init(&rnicp->qpidr); 109 idr_init(&rnicp->mmidr); 110 mtx_init(&rnicp->lock, "iwch rnic lock", NULL, MTX_DEF|MTX_DUPOK); 111 112 rnicp->attr.vendor_id = 0x168; 113 rnicp->attr.vendor_part_id = 7; 114 rnicp->attr.max_qps = T3_MAX_NUM_QP - 32; 115 rnicp->attr.max_wrs = (1UL << 24) - 1; 116 rnicp->attr.max_sge_per_wr = T3_MAX_SGE; 117 rnicp->attr.max_sge_per_rdma_write_wr = T3_MAX_SGE; 118 rnicp->attr.max_cqs = T3_MAX_NUM_CQ - 1; 119 rnicp->attr.max_cqes_per_cq = (1UL << 24) - 1; 120 rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev); 121 rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; 122 rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; 123 rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */ 124 rnicp->attr.can_resize_wq = 0; 125 rnicp->attr.max_rdma_reads_per_qp = 8; 126 rnicp->attr.max_rdma_read_resources = 127 rnicp->attr.max_rdma_reads_per_qp * rnicp->attr.max_qps; 128 rnicp->attr.max_rdma_read_qp_depth = 8; /* IRD */ 129 rnicp->attr.max_rdma_read_depth = 130 rnicp->attr.max_rdma_read_qp_depth * rnicp->attr.max_qps; 131 rnicp->attr.rq_overflow_handled = 0; 132 rnicp->attr.can_modify_ird = 0; 133 rnicp->attr.can_modify_ord = 0; 134 rnicp->attr.max_mem_windows = rnicp->attr.max_mem_regs - 1; 135 rnicp->attr.stag0_value = 1; 136 rnicp->attr.zbva_support = 1; 137 rnicp->attr.local_invalidate_fence = 1; 138 rnicp->attr.cq_overflow_detection = 1; 139 return; 140} 141 142static void 143open_rnic_dev(struct t3cdev *tdev) 144{ 145 struct iwch_dev *rnicp; 146 static int vers_printed; 147 148 CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev); 149 if (!vers_printed++) 150 printf("Chelsio T3 RDMA Driver - version %s\n", 151 DRV_VERSION); 152 rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp)); 153 if (!rnicp) { 154 printf("Cannot allocate ib device\n"); 155 return; 156 } 157 rnicp->rdev.ulp = rnicp; 158 rnicp->rdev.t3cdev_p = tdev; 159 160 mtx_lock(&dev_mutex); 161 162 if (cxio_rdev_open(&rnicp->rdev)) { 163 mtx_unlock(&dev_mutex); 164 printf("Unable to open CXIO rdev\n"); 165 ib_dealloc_device(&rnicp->ibdev); 166 return; 167 } 168 169 rnic_init(rnicp); 170 171 TAILQ_INSERT_TAIL(&dev_list, rnicp, entry); 172 mtx_unlock(&dev_mutex); 173 174 if (iwch_register_device(rnicp)) { 175 printf("Unable to register device\n"); 176 close_rnic_dev(tdev); 177 } 178#ifdef notyet 179 printf("Initialized device %s\n", 180 pci_name(rnicp->rdev.rnic_info.pdev)); 181#endif 182 return; 183} 184 185static void 186close_rnic_dev(struct t3cdev *tdev) 187{ 188 struct iwch_dev *dev, *tmp; 189 CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev); 190 mtx_lock(&dev_mutex); 191 192 TAILQ_FOREACH_SAFE(dev, &dev_list, entry, tmp) { 193 if (dev->rdev.t3cdev_p == tdev) { 194#ifdef notyet 195 list_del(&dev->entry); 196 iwch_unregister_device(dev); 197 cxio_rdev_close(&dev->rdev); 198 idr_destroy(&dev->cqidr); 199 idr_destroy(&dev->qpidr); 200 idr_destroy(&dev->mmidr); 201 ib_dealloc_device(&dev->ibdev); 202#endif 203 break; 204 } 205 } 206 mtx_unlock(&dev_mutex); 207} 208 209static ifaddr_event_handler_t 210ifaddr_event_handler(void *arg, struct ifnet *ifp) 211{ 212 printf("%s if name %s \n", __FUNCTION__, ifp->if_xname); 213 if (ifp->if_capabilities & IFCAP_TOE4) { 214 KASSERT(T3CDEV(ifp) != NULL, ("null t3cdev ptr!")); 215 if (cxio_hal_find_rdev_by_t3cdev(T3CDEV(ifp)) == NULL) 216 open_rnic_dev(T3CDEV(ifp)); 217 } 218 return 0; 219} 220 221 222static int 223iwch_init_module(void) 224{ 225 int err; 226 struct ifnet *ifp; 227 228 printf("%s enter\n", __FUNCTION__); 229 TAILQ_INIT(&dev_list); 230 mtx_init(&dev_mutex, "iwch dev_list lock", NULL, MTX_DEF); 231 232 err = cxio_hal_init(); 233 if (err) 234 return err; 235 err = iwch_cm_init(); 236 if (err) 237 return err; 238 cxio_register_ev_cb(iwch_ev_dispatch); 239 240 /* Register for ifaddr events to dynamically add TOE devs */ 241 event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_event_handler, 242 NULL, EVENTHANDLER_PRI_ANY); 243 244 /* Register existing TOE interfaces by walking the ifnet chain */ 245 IFNET_RLOCK(); 246 TAILQ_FOREACH(ifp, &V_ifnet, if_link) { 247 (void)ifaddr_event_handler(NULL, ifp); 248 } 249 IFNET_RUNLOCK(); 250 return 0; 251} 252 253static void 254iwch_exit_module(void) 255{ 256 EVENTHANDLER_DEREGISTER(ifaddr_event, event_tag); 257 cxio_unregister_ev_cb(iwch_ev_dispatch); 258 iwch_cm_term(); 259 cxio_hal_exit(); 260} 261 262static int 263iwch_load(module_t mod, int cmd, void *arg) 264{ 265 int err = 0; 266 267 switch (cmd) { 268 case MOD_LOAD: 269 printf("Loading iw_cxgb.\n"); 270 271 iwch_init_module(); 272 break; 273 case MOD_QUIESCE: 274 break; 275 case MOD_UNLOAD: 276 printf("Unloading iw_cxgb.\n"); 277 iwch_exit_module(); 278 break; 279 case MOD_SHUTDOWN: 280 break; 281 default: 282 err = EOPNOTSUPP; 283 break; 284 } 285 286 return (err); 287} 288 289static moduledata_t mod_data = { 290 "iw_cxgb", 291 iwch_load, 292 0 293}; 294 295MODULE_VERSION(iw_cxgb, 1); 296DECLARE_MODULE(iw_cxgb, mod_data, SI_SUB_EXEC, SI_ORDER_ANY); 297MODULE_DEPEND(iw_cxgb, rdma_core, 1, 1, 1); 298MODULE_DEPEND(iw_cxgb, if_cxgb, 1, 1, 1); 299MODULE_DEPEND(iw_cxgb, t3_tom, 1, 1, 1); 300 301