iw_cxgb.c revision 178786
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 178786 2008-05-05 18:46:18Z 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> 56178786Skmacy 57178786Skmacy#include <net/if.h> 58178786Skmacy#include <net/if_var.h> 59178786Skmacy 60178786Skmacy#include <netinet/in.h> 61178786Skmacy 62178786Skmacy#include <contrib/rdma/ib_verbs.h> 63178786Skmacy 64178786Skmacy 65178786Skmacy#ifdef CONFIG_DEFINED 66178786Skmacy#include <cxgb_include.h> 67178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_wr.h> 68178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_hal.h> 69178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_provider.h> 70178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_cm.h> 71178786Skmacy#include <ulp/iw_cxgb/iw_cxgb.h> 72178786Skmacy#else 73178786Skmacy#include <dev/cxgb/cxgb_include.h> 74178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_wr.h> 75178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_hal.h> 76178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_provider.h> 77178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.h> 78178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb.h> 79178786Skmacy#endif 80178786Skmacy 81178786Skmacy/* 82178786Skmacy * XXX :-/ 83178786Skmacy * 84178786Skmacy */ 85178786Skmacy 86178786Skmacy#define idr_init(x) 87178786Skmacy 88178786Skmacycxgb_cpl_handler_func t3c_handlers[NUM_CPL_CMDS]; 89178786Skmacy 90178786Skmacystatic void open_rnic_dev(struct t3cdev *); 91178786Skmacystatic void close_rnic_dev(struct t3cdev *); 92178786Skmacy 93178786Skmacystatic TAILQ_HEAD( ,iwch_dev) dev_list; 94178786Skmacystatic struct mtx dev_mutex; 95178786Skmacystatic eventhandler_tag event_tag; 96178786Skmacy 97178786Skmacystatic void 98178786Skmacyrnic_init(struct iwch_dev *rnicp) 99178786Skmacy{ 100178786Skmacy CTR2(KTR_IW_CXGB, "%s iwch_dev %p", __FUNCTION__, rnicp); 101178786Skmacy idr_init(&rnicp->cqidr); 102178786Skmacy idr_init(&rnicp->qpidr); 103178786Skmacy idr_init(&rnicp->mmidr); 104178786Skmacy mtx_init(&rnicp->lock, "iwch rnic lock", NULL, MTX_DEF|MTX_DUPOK); 105178786Skmacy 106178786Skmacy rnicp->attr.vendor_id = 0x168; 107178786Skmacy rnicp->attr.vendor_part_id = 7; 108178786Skmacy rnicp->attr.max_qps = T3_MAX_NUM_QP - 32; 109178786Skmacy rnicp->attr.max_wrs = (1UL << 24) - 1; 110178786Skmacy rnicp->attr.max_sge_per_wr = T3_MAX_SGE; 111178786Skmacy rnicp->attr.max_sge_per_rdma_write_wr = T3_MAX_SGE; 112178786Skmacy rnicp->attr.max_cqs = T3_MAX_NUM_CQ - 1; 113178786Skmacy rnicp->attr.max_cqes_per_cq = (1UL << 24) - 1; 114178786Skmacy rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev); 115178786Skmacy rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; 116178786Skmacy rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; 117178786Skmacy rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */ 118178786Skmacy rnicp->attr.can_resize_wq = 0; 119178786Skmacy rnicp->attr.max_rdma_reads_per_qp = 8; 120178786Skmacy rnicp->attr.max_rdma_read_resources = 121178786Skmacy rnicp->attr.max_rdma_reads_per_qp * rnicp->attr.max_qps; 122178786Skmacy rnicp->attr.max_rdma_read_qp_depth = 8; /* IRD */ 123178786Skmacy rnicp->attr.max_rdma_read_depth = 124178786Skmacy rnicp->attr.max_rdma_read_qp_depth * rnicp->attr.max_qps; 125178786Skmacy rnicp->attr.rq_overflow_handled = 0; 126178786Skmacy rnicp->attr.can_modify_ird = 0; 127178786Skmacy rnicp->attr.can_modify_ord = 0; 128178786Skmacy rnicp->attr.max_mem_windows = rnicp->attr.max_mem_regs - 1; 129178786Skmacy rnicp->attr.stag0_value = 1; 130178786Skmacy rnicp->attr.zbva_support = 1; 131178786Skmacy rnicp->attr.local_invalidate_fence = 1; 132178786Skmacy rnicp->attr.cq_overflow_detection = 1; 133178786Skmacy return; 134178786Skmacy} 135178786Skmacy 136178786Skmacystatic void 137178786Skmacyopen_rnic_dev(struct t3cdev *tdev) 138178786Skmacy{ 139178786Skmacy struct iwch_dev *rnicp; 140178786Skmacy static int vers_printed; 141178786Skmacy 142178786Skmacy CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev); 143178786Skmacy if (!vers_printed++) 144178786Skmacy printf("Chelsio T3 RDMA Driver - version %s\n", 145178786Skmacy DRV_VERSION); 146178786Skmacy rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp)); 147178786Skmacy if (!rnicp) { 148178786Skmacy printf("Cannot allocate ib device\n"); 149178786Skmacy return; 150178786Skmacy } 151178786Skmacy rnicp->rdev.ulp = rnicp; 152178786Skmacy rnicp->rdev.t3cdev_p = tdev; 153178786Skmacy 154178786Skmacy mtx_lock(&dev_mutex); 155178786Skmacy 156178786Skmacy if (cxio_rdev_open(&rnicp->rdev)) { 157178786Skmacy mtx_unlock(&dev_mutex); 158178786Skmacy printf("Unable to open CXIO rdev\n"); 159178786Skmacy ib_dealloc_device(&rnicp->ibdev); 160178786Skmacy return; 161178786Skmacy } 162178786Skmacy 163178786Skmacy rnic_init(rnicp); 164178786Skmacy 165178786Skmacy TAILQ_INSERT_TAIL(&dev_list, rnicp, entry); 166178786Skmacy mtx_unlock(&dev_mutex); 167178786Skmacy 168178786Skmacy if (iwch_register_device(rnicp)) { 169178786Skmacy printf("Unable to register device\n"); 170178786Skmacy close_rnic_dev(tdev); 171178786Skmacy } 172178786Skmacy#ifdef notyet 173178786Skmacy printf("Initialized device %s\n", 174178786Skmacy pci_name(rnicp->rdev.rnic_info.pdev)); 175178786Skmacy#endif 176178786Skmacy return; 177178786Skmacy} 178178786Skmacy 179178786Skmacystatic void 180178786Skmacyclose_rnic_dev(struct t3cdev *tdev) 181178786Skmacy{ 182178786Skmacy struct iwch_dev *dev, *tmp; 183178786Skmacy CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__, tdev); 184178786Skmacy mtx_lock(&dev_mutex); 185178786Skmacy 186178786Skmacy TAILQ_FOREACH_SAFE(dev, &dev_list, entry, tmp) { 187178786Skmacy if (dev->rdev.t3cdev_p == tdev) { 188178786Skmacy#ifdef notyet 189178786Skmacy list_del(&dev->entry); 190178786Skmacy iwch_unregister_device(dev); 191178786Skmacy cxio_rdev_close(&dev->rdev); 192178786Skmacy idr_destroy(&dev->cqidr); 193178786Skmacy idr_destroy(&dev->qpidr); 194178786Skmacy idr_destroy(&dev->mmidr); 195178786Skmacy ib_dealloc_device(&dev->ibdev); 196178786Skmacy#endif 197178786Skmacy break; 198178786Skmacy } 199178786Skmacy } 200178786Skmacy mtx_unlock(&dev_mutex); 201178786Skmacy} 202178786Skmacy 203178786Skmacystatic ifaddr_event_handler_t 204178786Skmacyifaddr_event_handler(void *arg, struct ifnet *ifp) 205178786Skmacy{ 206178786Skmacy printf("%s if name %s \n", __FUNCTION__, ifp->if_xname); 207178786Skmacy if (ifp->if_capabilities & IFCAP_TOE4) { 208178786Skmacy KASSERT(T3CDEV(ifp) != NULL, ("null t3cdev ptr!")); 209178786Skmacy if (cxio_hal_find_rdev_by_t3cdev(T3CDEV(ifp)) == NULL) 210178786Skmacy open_rnic_dev(T3CDEV(ifp)); 211178786Skmacy } 212178786Skmacy return 0; 213178786Skmacy} 214178786Skmacy 215178786Skmacy 216178786Skmacystatic int 217178786Skmacyiwch_init_module(void) 218178786Skmacy{ 219178786Skmacy int err; 220178786Skmacy struct ifnet *ifp; 221178786Skmacy 222178786Skmacy printf("%s enter\n", __FUNCTION__); 223178786Skmacy TAILQ_INIT(&dev_list); 224178786Skmacy mtx_init(&dev_mutex, "iwch dev_list lock", NULL, MTX_DEF); 225178786Skmacy 226178786Skmacy err = cxio_hal_init(); 227178786Skmacy if (err) 228178786Skmacy return err; 229178786Skmacy err = iwch_cm_init(); 230178786Skmacy if (err) 231178786Skmacy return err; 232178786Skmacy cxio_register_ev_cb(iwch_ev_dispatch); 233178786Skmacy 234178786Skmacy /* Register for ifaddr events to dynamically add TOE devs */ 235178786Skmacy event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_event_handler, 236178786Skmacy NULL, EVENTHANDLER_PRI_ANY); 237178786Skmacy 238178786Skmacy /* Register existing TOE interfaces by walking the ifnet chain */ 239178786Skmacy IFNET_RLOCK(); 240178786Skmacy TAILQ_FOREACH(ifp, &ifnet, if_link) { 241178786Skmacy (void)ifaddr_event_handler(NULL, ifp); 242178786Skmacy } 243178786Skmacy IFNET_RUNLOCK(); 244178786Skmacy return 0; 245178786Skmacy} 246178786Skmacy 247178786Skmacystatic void 248178786Skmacyiwch_exit_module(void) 249178786Skmacy{ 250178786Skmacy EVENTHANDLER_DEREGISTER(ifaddr_event, event_tag); 251178786Skmacy cxio_unregister_ev_cb(iwch_ev_dispatch); 252178786Skmacy iwch_cm_term(); 253178786Skmacy cxio_hal_exit(); 254178786Skmacy} 255178786Skmacy 256178786Skmacystatic int 257178786Skmacyiwch_load(module_t mod, int cmd, void *arg) 258178786Skmacy{ 259178786Skmacy int err = 0; 260178786Skmacy 261178786Skmacy switch (cmd) { 262178786Skmacy case MOD_LOAD: 263178786Skmacy printf("Loading iw_cxgb.\n"); 264178786Skmacy 265178786Skmacy iwch_init_module(); 266178786Skmacy break; 267178786Skmacy case MOD_QUIESCE: 268178786Skmacy break; 269178786Skmacy case MOD_UNLOAD: 270178786Skmacy printf("Unloading iw_cxgb.\n"); 271178786Skmacy iwch_exit_module(); 272178786Skmacy break; 273178786Skmacy case MOD_SHUTDOWN: 274178786Skmacy break; 275178786Skmacy default: 276178786Skmacy err = EOPNOTSUPP; 277178786Skmacy break; 278178786Skmacy } 279178786Skmacy 280178786Skmacy return (err); 281178786Skmacy} 282178786Skmacy 283178786Skmacystatic moduledata_t mod_data = { 284178786Skmacy "iw_cxgb", 285178786Skmacy iwch_load, 286178786Skmacy 0 287178786Skmacy}; 288178786Skmacy 289178786SkmacyMODULE_VERSION(iw_cxgb, 1); 290178786SkmacyDECLARE_MODULE(iw_cxgb, mod_data, SI_SUB_EXEC, SI_ORDER_ANY); 291178786SkmacyMODULE_DEPEND(iw_cxgb, rdma_core, 1, 1, 1); 292178786SkmacyMODULE_DEPEND(iw_cxgb, if_cxgb, 1, 1, 1); 293178786SkmacyMODULE_DEPEND(iw_cxgb, t3_tom, 1, 1, 1); 294178786Skmacy 295