iw_cxgb.c revision 183289
1178786Skmacy/************************************************************************** 2178786Skmacy 3178786SkmacyCopyright (c) 2007, Chelsio Inc. 4178786SkmacyAll rights reserved. 5178786Skmacy 6178786SkmacyRedistribution and use in source and binary forms, with or without 7178786Skmacymodification, are permitted provided that the following conditions are met: 8178786Skmacy 9178786Skmacy 1. Redistributions of source code must retain the above copyright notice, 10178786Skmacy this list of conditions and the following disclaimer. 11178786Skmacy 12178786Skmacy 2. Neither the name of the Chelsio Corporation nor the names of its 13178786Skmacy contributors may be used to endorse or promote products derived from 14178786Skmacy this software without specific prior written permission. 15178786Skmacy 16178786SkmacyTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17178786SkmacyAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18178786SkmacyIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19178786SkmacyARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20178786SkmacyLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21178786SkmacyCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22178786SkmacySUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23178786SkmacyINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24178786SkmacyCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25178786SkmacyARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26178786SkmacyPOSSIBILITY OF SUCH DAMAGE. 27178786Skmacy 28178786Skmacy***************************************************************************/ 29178786Skmacy#include <sys/cdefs.h> 30178786Skmacy__FBSDID("$FreeBSD: head/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb.c 183289 2008-09-23 02:22:24Z kmacy $"); 31178786Skmacy 32178786Skmacy#include <sys/param.h> 33178786Skmacy#include <sys/systm.h> 34178786Skmacy#include <sys/kernel.h> 35178786Skmacy#include <sys/bus.h> 36178786Skmacy#include <sys/module.h> 37178786Skmacy#include <sys/pciio.h> 38178786Skmacy#include <sys/conf.h> 39178786Skmacy#include <machine/bus.h> 40178786Skmacy#include <machine/resource.h> 41178786Skmacy#include <sys/bus_dma.h> 42178786Skmacy#include <sys/rman.h> 43178786Skmacy#include <sys/ioccom.h> 44178786Skmacy#include <sys/mbuf.h> 45178786Skmacy#include <sys/rwlock.h> 46178786Skmacy#include <sys/linker.h> 47178786Skmacy#include <sys/firmware.h> 48178786Skmacy#include <sys/socket.h> 49178786Skmacy#include <sys/sockio.h> 50178786Skmacy#include <sys/smp.h> 51178786Skmacy#include <sys/sysctl.h> 52178786Skmacy#include <sys/queue.h> 53178786Skmacy#include <sys/taskqueue.h> 54178786Skmacy#include <sys/proc.h> 55178786Skmacy#include <sys/eventhandler.h> 56183289Skmacy 57183289Skmacy#if __FreeBSD_version >= 800044 58182741Sjulian#include <sys/vimage.h> 59183289Skmacy#else 60183289Skmacy#define V_ifnet ifnet 61183289Skmacy#endif 62178786Skmacy 63178786Skmacy#include <net/if.h> 64178786Skmacy#include <net/if_var.h> 65178786Skmacy 66178786Skmacy#include <netinet/in.h> 67178786Skmacy 68178786Skmacy#include <contrib/rdma/ib_verbs.h> 69178786Skmacy 70178786Skmacy 71178786Skmacy#ifdef CONFIG_DEFINED 72178786Skmacy#include <cxgb_include.h> 73178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_wr.h> 74178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_hal.h> 75178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_provider.h> 76178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_cm.h> 77178786Skmacy#include <ulp/iw_cxgb/iw_cxgb.h> 78178786Skmacy#else 79178786Skmacy#include <dev/cxgb/cxgb_include.h> 80178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_wr.h> 81178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_hal.h> 82178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_provider.h> 83178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.h> 84178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb.h> 85178786Skmacy#endif 86178786Skmacy 87178786Skmacy/* 88178786Skmacy * XXX :-/ 89178786Skmacy * 90178786Skmacy */ 91178786Skmacy 92178786Skmacy#define idr_init(x) 93178786Skmacy 94178786Skmacycxgb_cpl_handler_func t3c_handlers[NUM_CPL_CMDS]; 95178786Skmacy 96178786Skmacystatic void open_rnic_dev(struct t3cdev *); 97178786Skmacystatic void close_rnic_dev(struct t3cdev *); 98178786Skmacy 99178786Skmacystatic TAILQ_HEAD( ,iwch_dev) dev_list; 100178786Skmacystatic struct mtx dev_mutex; 101178786Skmacystatic eventhandler_tag event_tag; 102178786Skmacy 103178786Skmacystatic void 104178786Skmacyrnic_init(struct iwch_dev *rnicp) 105178786Skmacy{ 106178786Skmacy CTR2(KTR_IW_CXGB, "%s iwch_dev %p", __FUNCTION__, rnicp); 107178786Skmacy idr_init(&rnicp->cqidr); 108178786Skmacy idr_init(&rnicp->qpidr); 109178786Skmacy idr_init(&rnicp->mmidr); 110178786Skmacy mtx_init(&rnicp->lock, "iwch rnic lock", NULL, MTX_DEF|MTX_DUPOK); 111178786Skmacy 112178786Skmacy rnicp->attr.vendor_id = 0x168; 113178786Skmacy rnicp->attr.vendor_part_id = 7; 114178786Skmacy rnicp->attr.max_qps = T3_MAX_NUM_QP - 32; 115178786Skmacy rnicp->attr.max_wrs = (1UL << 24) - 1; 116178786Skmacy rnicp->attr.max_sge_per_wr = T3_MAX_SGE; 117178786Skmacy rnicp->attr.max_sge_per_rdma_write_wr = T3_MAX_SGE; 118178786Skmacy rnicp->attr.max_cqs = T3_MAX_NUM_CQ - 1; 119178786Skmacy rnicp->attr.max_cqes_per_cq = (1UL << 24) - 1; 120178786Skmacy rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev); 121178786Skmacy rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; 122178786Skmacy rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; 123178786Skmacy rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */ 124178786Skmacy rnicp->attr.can_resize_wq = 0; 125178786Skmacy rnicp->attr.max_rdma_reads_per_qp = 8; 126178786Skmacy rnicp->attr.max_rdma_read_resources = 127178786Skmacy rnicp->attr.max_rdma_reads_per_qp * rnicp->attr.max_qps; 128178786Skmacy rnicp->attr.max_rdma_read_qp_depth = 8; /* IRD */ 129178786Skmacy rnicp->attr.max_rdma_read_depth = 130178786Skmacy rnicp->attr.max_rdma_read_qp_depth * rnicp->attr.max_qps; 131178786Skmacy rnicp->attr.rq_overflow_handled = 0; 132178786Skmacy rnicp->attr.can_modify_ird = 0; 133178786Skmacy rnicp->attr.can_modify_ord = 0; 134178786Skmacy rnicp->attr.max_mem_windows = rnicp->attr.max_mem_regs - 1; 135178786Skmacy rnicp->attr.stag0_value = 1; 136178786Skmacy rnicp->attr.zbva_support = 1; 137178786Skmacy rnicp->attr.local_invalidate_fence = 1; 138178786Skmacy rnicp->attr.cq_overflow_detection = 1; 139178786Skmacy return; 140178786Skmacy} 141178786Skmacy 142178786Skmacystatic void 143178786Skmacyopen_rnic_dev(struct t3cdev *tdev) 144178786Skmacy{ 145178786Skmacy struct iwch_dev *rnicp; 146178786Skmacy static int vers_printed; 147178786Skmacy 148178786Skmacy CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev); 149178786Skmacy if (!vers_printed++) 150178786Skmacy printf("Chelsio T3 RDMA Driver - version %s\n", 151178786Skmacy DRV_VERSION); 152178786Skmacy rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp)); 153178786Skmacy if (!rnicp) { 154178786Skmacy printf("Cannot allocate ib device\n"); 155178786Skmacy return; 156178786Skmacy } 157178786Skmacy rnicp->rdev.ulp = rnicp; 158178786Skmacy rnicp->rdev.t3cdev_p = tdev; 159178786Skmacy 160178786Skmacy mtx_lock(&dev_mutex); 161178786Skmacy 162178786Skmacy if (cxio_rdev_open(&rnicp->rdev)) { 163178786Skmacy mtx_unlock(&dev_mutex); 164178786Skmacy printf("Unable to open CXIO rdev\n"); 165178786Skmacy ib_dealloc_device(&rnicp->ibdev); 166178786Skmacy return; 167178786Skmacy } 168178786Skmacy 169178786Skmacy rnic_init(rnicp); 170178786Skmacy 171178786Skmacy TAILQ_INSERT_TAIL(&dev_list, rnicp, entry); 172178786Skmacy mtx_unlock(&dev_mutex); 173178786Skmacy 174178786Skmacy if (iwch_register_device(rnicp)) { 175178786Skmacy printf("Unable to register device\n"); 176178786Skmacy close_rnic_dev(tdev); 177178786Skmacy } 178178786Skmacy#ifdef notyet 179178786Skmacy printf("Initialized device %s\n", 180178786Skmacy pci_name(rnicp->rdev.rnic_info.pdev)); 181178786Skmacy#endif 182178786Skmacy return; 183178786Skmacy} 184178786Skmacy 185178786Skmacystatic void 186178786Skmacyclose_rnic_dev(struct t3cdev *tdev) 187178786Skmacy{ 188178786Skmacy struct iwch_dev *dev, *tmp; 189178786Skmacy CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev); 190178786Skmacy mtx_lock(&dev_mutex); 191178786Skmacy 192178786Skmacy TAILQ_FOREACH_SAFE(dev, &dev_list, entry, tmp) { 193178786Skmacy if (dev->rdev.t3cdev_p == tdev) { 194178786Skmacy#ifdef notyet 195178786Skmacy list_del(&dev->entry); 196178786Skmacy iwch_unregister_device(dev); 197178786Skmacy cxio_rdev_close(&dev->rdev); 198178786Skmacy idr_destroy(&dev->cqidr); 199178786Skmacy idr_destroy(&dev->qpidr); 200178786Skmacy idr_destroy(&dev->mmidr); 201178786Skmacy ib_dealloc_device(&dev->ibdev); 202178786Skmacy#endif 203178786Skmacy break; 204178786Skmacy } 205178786Skmacy } 206178786Skmacy mtx_unlock(&dev_mutex); 207178786Skmacy} 208178786Skmacy 209178786Skmacystatic ifaddr_event_handler_t 210178786Skmacyifaddr_event_handler(void *arg, struct ifnet *ifp) 211178786Skmacy{ 212178786Skmacy printf("%s if name %s \n", __FUNCTION__, ifp->if_xname); 213178786Skmacy if (ifp->if_capabilities & IFCAP_TOE4) { 214178786Skmacy KASSERT(T3CDEV(ifp) != NULL, ("null t3cdev ptr!")); 215178786Skmacy if (cxio_hal_find_rdev_by_t3cdev(T3CDEV(ifp)) == NULL) 216178786Skmacy open_rnic_dev(T3CDEV(ifp)); 217178786Skmacy } 218178786Skmacy return 0; 219178786Skmacy} 220178786Skmacy 221178786Skmacy 222178786Skmacystatic int 223178786Skmacyiwch_init_module(void) 224178786Skmacy{ 225178786Skmacy int err; 226178786Skmacy struct ifnet *ifp; 227178786Skmacy 228178786Skmacy printf("%s enter\n", __FUNCTION__); 229178786Skmacy TAILQ_INIT(&dev_list); 230178786Skmacy mtx_init(&dev_mutex, "iwch dev_list lock", NULL, MTX_DEF); 231178786Skmacy 232178786Skmacy err = cxio_hal_init(); 233178786Skmacy if (err) 234178786Skmacy return err; 235178786Skmacy err = iwch_cm_init(); 236178786Skmacy if (err) 237178786Skmacy return err; 238178786Skmacy cxio_register_ev_cb(iwch_ev_dispatch); 239178786Skmacy 240178786Skmacy /* Register for ifaddr events to dynamically add TOE devs */ 241178786Skmacy event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_event_handler, 242178786Skmacy NULL, EVENTHANDLER_PRI_ANY); 243178786Skmacy 244178786Skmacy /* Register existing TOE interfaces by walking the ifnet chain */ 245178786Skmacy IFNET_RLOCK(); 246182741Sjulian TAILQ_FOREACH(ifp, &V_ifnet, if_link) { 247178786Skmacy (void)ifaddr_event_handler(NULL, ifp); 248178786Skmacy } 249178786Skmacy IFNET_RUNLOCK(); 250178786Skmacy return 0; 251178786Skmacy} 252178786Skmacy 253178786Skmacystatic void 254178786Skmacyiwch_exit_module(void) 255178786Skmacy{ 256178786Skmacy EVENTHANDLER_DEREGISTER(ifaddr_event, event_tag); 257178786Skmacy cxio_unregister_ev_cb(iwch_ev_dispatch); 258178786Skmacy iwch_cm_term(); 259178786Skmacy cxio_hal_exit(); 260178786Skmacy} 261178786Skmacy 262178786Skmacystatic int 263178786Skmacyiwch_load(module_t mod, int cmd, void *arg) 264178786Skmacy{ 265178786Skmacy int err = 0; 266178786Skmacy 267178786Skmacy switch (cmd) { 268178786Skmacy case MOD_LOAD: 269178786Skmacy printf("Loading iw_cxgb.\n"); 270178786Skmacy 271178786Skmacy iwch_init_module(); 272178786Skmacy break; 273178786Skmacy case MOD_QUIESCE: 274178786Skmacy break; 275178786Skmacy case MOD_UNLOAD: 276178786Skmacy printf("Unloading iw_cxgb.\n"); 277178786Skmacy iwch_exit_module(); 278178786Skmacy break; 279178786Skmacy case MOD_SHUTDOWN: 280178786Skmacy break; 281178786Skmacy default: 282178786Skmacy err = EOPNOTSUPP; 283178786Skmacy break; 284178786Skmacy } 285178786Skmacy 286178786Skmacy return (err); 287178786Skmacy} 288178786Skmacy 289178786Skmacystatic moduledata_t mod_data = { 290178786Skmacy "iw_cxgb", 291178786Skmacy iwch_load, 292178786Skmacy 0 293178786Skmacy}; 294178786Skmacy 295178786SkmacyMODULE_VERSION(iw_cxgb, 1); 296178786SkmacyDECLARE_MODULE(iw_cxgb, mod_data, SI_SUB_EXEC, SI_ORDER_ANY); 297178786SkmacyMODULE_DEPEND(iw_cxgb, rdma_core, 1, 1, 1); 298178786SkmacyMODULE_DEPEND(iw_cxgb, if_cxgb, 1, 1, 1); 299178786SkmacyMODULE_DEPEND(iw_cxgb, t3_tom, 1, 1, 1); 300178786Skmacy 301