162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved. 362306a36Sopenharmony_ci * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. 462306a36Sopenharmony_ci * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * This software is available to you under a choice of one of two 762306a36Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 862306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 962306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the 1062306a36Sopenharmony_ci * OpenIB.org BSD license below: 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or 1362306a36Sopenharmony_ci * without modification, are permitted provided that the following 1462306a36Sopenharmony_ci * conditions are met: 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * - Redistributions of source code must retain the above 1762306a36Sopenharmony_ci * copyright notice, this list of conditions and the following 1862306a36Sopenharmony_ci * disclaimer. 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * - Redistributions in binary form must reproduce the above 2162306a36Sopenharmony_ci * copyright notice, this list of conditions and the following 2262306a36Sopenharmony_ci * disclaimer in the documentation and/or other materials 2362306a36Sopenharmony_ci * provided with the distribution. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2662306a36Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2762306a36Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2862306a36Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 2962306a36Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3062306a36Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3162306a36Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3262306a36Sopenharmony_ci * SOFTWARE. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#include <linux/pci.h> 3662306a36Sopenharmony_ci#include <linux/netdevice.h> 3762306a36Sopenharmony_ci#include <linux/vmalloc.h> 3862306a36Sopenharmony_ci#include <linux/delay.h> 3962306a36Sopenharmony_ci#include <linux/module.h> 4062306a36Sopenharmony_ci#include <linux/printk.h> 4162306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_QIB_DCA 4262306a36Sopenharmony_ci#include <linux/dca.h> 4362306a36Sopenharmony_ci#endif 4462306a36Sopenharmony_ci#include <rdma/rdma_vt.h> 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#include "qib.h" 4762306a36Sopenharmony_ci#include "qib_common.h" 4862306a36Sopenharmony_ci#include "qib_mad.h" 4962306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 5062306a36Sopenharmony_ci#include "qib_debugfs.h" 5162306a36Sopenharmony_ci#include "qib_verbs.h" 5262306a36Sopenharmony_ci#endif 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#undef pr_fmt 5562306a36Sopenharmony_ci#define pr_fmt(fmt) QIB_DRV_NAME ": " fmt 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci/* 5862306a36Sopenharmony_ci * min buffers we want to have per context, after driver 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_ci#define QIB_MIN_USER_CTXT_BUFCNT 7 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#define QLOGIC_IB_R_SOFTWARE_MASK 0xFF 6362306a36Sopenharmony_ci#define QLOGIC_IB_R_SOFTWARE_SHIFT 24 6462306a36Sopenharmony_ci#define QLOGIC_IB_R_EMULATOR_MASK (1ULL<<62) 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* 6762306a36Sopenharmony_ci * Number of ctxts we are configured to use (to allow for more pio 6862306a36Sopenharmony_ci * buffers per ctxt, etc.) Zero means use chip value. 6962306a36Sopenharmony_ci */ 7062306a36Sopenharmony_ciushort qib_cfgctxts; 7162306a36Sopenharmony_cimodule_param_named(cfgctxts, qib_cfgctxts, ushort, S_IRUGO); 7262306a36Sopenharmony_ciMODULE_PARM_DESC(cfgctxts, "Set max number of contexts to use"); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ciunsigned qib_numa_aware; 7562306a36Sopenharmony_cimodule_param_named(numa_aware, qib_numa_aware, uint, S_IRUGO); 7662306a36Sopenharmony_ciMODULE_PARM_DESC(numa_aware, 7762306a36Sopenharmony_ci "0 -> PSM allocation close to HCA, 1 -> PSM allocation local to process"); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/* 8062306a36Sopenharmony_ci * If set, do not write to any regs if avoidable, hack to allow 8162306a36Sopenharmony_ci * check for deranged default register values. 8262306a36Sopenharmony_ci */ 8362306a36Sopenharmony_ciushort qib_mini_init; 8462306a36Sopenharmony_cimodule_param_named(mini_init, qib_mini_init, ushort, S_IRUGO); 8562306a36Sopenharmony_ciMODULE_PARM_DESC(mini_init, "If set, do minimal diag init"); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ciunsigned qib_n_krcv_queues; 8862306a36Sopenharmony_cimodule_param_named(krcvqs, qib_n_krcv_queues, uint, S_IRUGO); 8962306a36Sopenharmony_ciMODULE_PARM_DESC(krcvqs, "number of kernel receive queues per IB port"); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ciunsigned qib_cc_table_size; 9262306a36Sopenharmony_cimodule_param_named(cc_table_size, qib_cc_table_size, uint, S_IRUGO); 9362306a36Sopenharmony_ciMODULE_PARM_DESC(cc_table_size, "Congestion control table entries 0 (CCA disabled - default), min = 128, max = 1984"); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistatic void verify_interrupt(struct timer_list *); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ciDEFINE_XARRAY_FLAGS(qib_dev_table, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ); 9862306a36Sopenharmony_ciu32 qib_cpulist_count; 9962306a36Sopenharmony_ciunsigned long *qib_cpulist; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/* set number of contexts we'll actually use */ 10262306a36Sopenharmony_civoid qib_set_ctxtcnt(struct qib_devdata *dd) 10362306a36Sopenharmony_ci{ 10462306a36Sopenharmony_ci if (!qib_cfgctxts) { 10562306a36Sopenharmony_ci dd->cfgctxts = dd->first_user_ctxt + num_online_cpus(); 10662306a36Sopenharmony_ci if (dd->cfgctxts > dd->ctxtcnt) 10762306a36Sopenharmony_ci dd->cfgctxts = dd->ctxtcnt; 10862306a36Sopenharmony_ci } else if (qib_cfgctxts < dd->num_pports) 10962306a36Sopenharmony_ci dd->cfgctxts = dd->ctxtcnt; 11062306a36Sopenharmony_ci else if (qib_cfgctxts <= dd->ctxtcnt) 11162306a36Sopenharmony_ci dd->cfgctxts = qib_cfgctxts; 11262306a36Sopenharmony_ci else 11362306a36Sopenharmony_ci dd->cfgctxts = dd->ctxtcnt; 11462306a36Sopenharmony_ci dd->freectxts = (dd->first_user_ctxt > dd->cfgctxts) ? 0 : 11562306a36Sopenharmony_ci dd->cfgctxts - dd->first_user_ctxt; 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci/* 11962306a36Sopenharmony_ci * Common code for creating the receive context array. 12062306a36Sopenharmony_ci */ 12162306a36Sopenharmony_ciint qib_create_ctxts(struct qib_devdata *dd) 12262306a36Sopenharmony_ci{ 12362306a36Sopenharmony_ci unsigned i; 12462306a36Sopenharmony_ci int local_node_id = pcibus_to_node(dd->pcidev->bus); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci if (local_node_id < 0) 12762306a36Sopenharmony_ci local_node_id = numa_node_id(); 12862306a36Sopenharmony_ci dd->assigned_node_id = local_node_id; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci /* 13162306a36Sopenharmony_ci * Allocate full ctxtcnt array, rather than just cfgctxts, because 13262306a36Sopenharmony_ci * cleanup iterates across all possible ctxts. 13362306a36Sopenharmony_ci */ 13462306a36Sopenharmony_ci dd->rcd = kcalloc(dd->ctxtcnt, sizeof(*dd->rcd), GFP_KERNEL); 13562306a36Sopenharmony_ci if (!dd->rcd) 13662306a36Sopenharmony_ci return -ENOMEM; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci /* create (one or more) kctxt */ 13962306a36Sopenharmony_ci for (i = 0; i < dd->first_user_ctxt; ++i) { 14062306a36Sopenharmony_ci struct qib_pportdata *ppd; 14162306a36Sopenharmony_ci struct qib_ctxtdata *rcd; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci if (dd->skip_kctxt_mask & (1 << i)) 14462306a36Sopenharmony_ci continue; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci ppd = dd->pport + (i % dd->num_pports); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci rcd = qib_create_ctxtdata(ppd, i, dd->assigned_node_id); 14962306a36Sopenharmony_ci if (!rcd) { 15062306a36Sopenharmony_ci qib_dev_err(dd, 15162306a36Sopenharmony_ci "Unable to allocate ctxtdata for Kernel ctxt, failing\n"); 15262306a36Sopenharmony_ci kfree(dd->rcd); 15362306a36Sopenharmony_ci dd->rcd = NULL; 15462306a36Sopenharmony_ci return -ENOMEM; 15562306a36Sopenharmony_ci } 15662306a36Sopenharmony_ci rcd->pkeys[0] = QIB_DEFAULT_P_KEY; 15762306a36Sopenharmony_ci rcd->seq_cnt = 1; 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci return 0; 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci/* 16362306a36Sopenharmony_ci * Common code for user and kernel context setup. 16462306a36Sopenharmony_ci */ 16562306a36Sopenharmony_cistruct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *ppd, u32 ctxt, 16662306a36Sopenharmony_ci int node_id) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci struct qib_devdata *dd = ppd->dd; 16962306a36Sopenharmony_ci struct qib_ctxtdata *rcd; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci rcd = kzalloc_node(sizeof(*rcd), GFP_KERNEL, node_id); 17262306a36Sopenharmony_ci if (rcd) { 17362306a36Sopenharmony_ci INIT_LIST_HEAD(&rcd->qp_wait_list); 17462306a36Sopenharmony_ci rcd->node_id = node_id; 17562306a36Sopenharmony_ci rcd->ppd = ppd; 17662306a36Sopenharmony_ci rcd->dd = dd; 17762306a36Sopenharmony_ci rcd->cnt = 1; 17862306a36Sopenharmony_ci rcd->ctxt = ctxt; 17962306a36Sopenharmony_ci dd->rcd[ctxt] = rcd; 18062306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 18162306a36Sopenharmony_ci if (ctxt < dd->first_user_ctxt) { /* N/A for PSM contexts */ 18262306a36Sopenharmony_ci rcd->opstats = kzalloc_node(sizeof(*rcd->opstats), 18362306a36Sopenharmony_ci GFP_KERNEL, node_id); 18462306a36Sopenharmony_ci if (!rcd->opstats) { 18562306a36Sopenharmony_ci kfree(rcd); 18662306a36Sopenharmony_ci qib_dev_err(dd, 18762306a36Sopenharmony_ci "Unable to allocate per ctxt stats buffer\n"); 18862306a36Sopenharmony_ci return NULL; 18962306a36Sopenharmony_ci } 19062306a36Sopenharmony_ci } 19162306a36Sopenharmony_ci#endif 19262306a36Sopenharmony_ci dd->f_init_ctxt(rcd); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci /* 19562306a36Sopenharmony_ci * To avoid wasting a lot of memory, we allocate 32KB chunks 19662306a36Sopenharmony_ci * of physically contiguous memory, advance through it until 19762306a36Sopenharmony_ci * used up and then allocate more. Of course, we need 19862306a36Sopenharmony_ci * memory to store those extra pointers, now. 32KB seems to 19962306a36Sopenharmony_ci * be the most that is "safe" under memory pressure 20062306a36Sopenharmony_ci * (creating large files and then copying them over 20162306a36Sopenharmony_ci * NFS while doing lots of MPI jobs). The OOM killer can 20262306a36Sopenharmony_ci * get invoked, even though we say we can sleep and this can 20362306a36Sopenharmony_ci * cause significant system problems.... 20462306a36Sopenharmony_ci */ 20562306a36Sopenharmony_ci rcd->rcvegrbuf_size = 0x8000; 20662306a36Sopenharmony_ci rcd->rcvegrbufs_perchunk = 20762306a36Sopenharmony_ci rcd->rcvegrbuf_size / dd->rcvegrbufsize; 20862306a36Sopenharmony_ci rcd->rcvegrbuf_chunks = (rcd->rcvegrcnt + 20962306a36Sopenharmony_ci rcd->rcvegrbufs_perchunk - 1) / 21062306a36Sopenharmony_ci rcd->rcvegrbufs_perchunk; 21162306a36Sopenharmony_ci rcd->rcvegrbufs_perchunk_shift = 21262306a36Sopenharmony_ci ilog2(rcd->rcvegrbufs_perchunk); 21362306a36Sopenharmony_ci } 21462306a36Sopenharmony_ci return rcd; 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci/* 21862306a36Sopenharmony_ci * Common code for initializing the physical port structure. 21962306a36Sopenharmony_ci */ 22062306a36Sopenharmony_ciint qib_init_pportdata(struct qib_pportdata *ppd, struct qib_devdata *dd, 22162306a36Sopenharmony_ci u8 hw_pidx, u8 port) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci int size; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci ppd->dd = dd; 22662306a36Sopenharmony_ci ppd->hw_pidx = hw_pidx; 22762306a36Sopenharmony_ci ppd->port = port; /* IB port number, not index */ 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci spin_lock_init(&ppd->sdma_lock); 23062306a36Sopenharmony_ci spin_lock_init(&ppd->lflags_lock); 23162306a36Sopenharmony_ci spin_lock_init(&ppd->cc_shadow_lock); 23262306a36Sopenharmony_ci init_waitqueue_head(&ppd->state_wait); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci timer_setup(&ppd->symerr_clear_timer, qib_clear_symerror_on_linkup, 0); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci ppd->qib_wq = NULL; 23762306a36Sopenharmony_ci ppd->ibport_data.pmastats = 23862306a36Sopenharmony_ci alloc_percpu(struct qib_pma_counters); 23962306a36Sopenharmony_ci if (!ppd->ibport_data.pmastats) 24062306a36Sopenharmony_ci return -ENOMEM; 24162306a36Sopenharmony_ci ppd->ibport_data.rvp.rc_acks = alloc_percpu(u64); 24262306a36Sopenharmony_ci ppd->ibport_data.rvp.rc_qacks = alloc_percpu(u64); 24362306a36Sopenharmony_ci ppd->ibport_data.rvp.rc_delayed_comp = alloc_percpu(u64); 24462306a36Sopenharmony_ci if (!(ppd->ibport_data.rvp.rc_acks) || 24562306a36Sopenharmony_ci !(ppd->ibport_data.rvp.rc_qacks) || 24662306a36Sopenharmony_ci !(ppd->ibport_data.rvp.rc_delayed_comp)) 24762306a36Sopenharmony_ci return -ENOMEM; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci if (qib_cc_table_size < IB_CCT_MIN_ENTRIES) 25062306a36Sopenharmony_ci goto bail; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci ppd->cc_supported_table_entries = min(max_t(int, qib_cc_table_size, 25362306a36Sopenharmony_ci IB_CCT_MIN_ENTRIES), IB_CCT_ENTRIES*IB_CC_TABLE_CAP_DEFAULT); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci ppd->cc_max_table_entries = 25662306a36Sopenharmony_ci ppd->cc_supported_table_entries/IB_CCT_ENTRIES; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci size = IB_CC_TABLE_CAP_DEFAULT * sizeof(struct ib_cc_table_entry) 25962306a36Sopenharmony_ci * IB_CCT_ENTRIES; 26062306a36Sopenharmony_ci ppd->ccti_entries = kzalloc(size, GFP_KERNEL); 26162306a36Sopenharmony_ci if (!ppd->ccti_entries) 26262306a36Sopenharmony_ci goto bail; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci size = IB_CC_CCS_ENTRIES * sizeof(struct ib_cc_congestion_entry); 26562306a36Sopenharmony_ci ppd->congestion_entries = kzalloc(size, GFP_KERNEL); 26662306a36Sopenharmony_ci if (!ppd->congestion_entries) 26762306a36Sopenharmony_ci goto bail_1; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci size = sizeof(struct cc_table_shadow); 27062306a36Sopenharmony_ci ppd->ccti_entries_shadow = kzalloc(size, GFP_KERNEL); 27162306a36Sopenharmony_ci if (!ppd->ccti_entries_shadow) 27262306a36Sopenharmony_ci goto bail_2; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci size = sizeof(struct ib_cc_congestion_setting_attr); 27562306a36Sopenharmony_ci ppd->congestion_entries_shadow = kzalloc(size, GFP_KERNEL); 27662306a36Sopenharmony_ci if (!ppd->congestion_entries_shadow) 27762306a36Sopenharmony_ci goto bail_3; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci return 0; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_cibail_3: 28262306a36Sopenharmony_ci kfree(ppd->ccti_entries_shadow); 28362306a36Sopenharmony_ci ppd->ccti_entries_shadow = NULL; 28462306a36Sopenharmony_cibail_2: 28562306a36Sopenharmony_ci kfree(ppd->congestion_entries); 28662306a36Sopenharmony_ci ppd->congestion_entries = NULL; 28762306a36Sopenharmony_cibail_1: 28862306a36Sopenharmony_ci kfree(ppd->ccti_entries); 28962306a36Sopenharmony_ci ppd->ccti_entries = NULL; 29062306a36Sopenharmony_cibail: 29162306a36Sopenharmony_ci /* User is intentionally disabling the congestion control agent */ 29262306a36Sopenharmony_ci if (!qib_cc_table_size) 29362306a36Sopenharmony_ci return 0; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci if (qib_cc_table_size < IB_CCT_MIN_ENTRIES) { 29662306a36Sopenharmony_ci qib_cc_table_size = 0; 29762306a36Sopenharmony_ci qib_dev_err(dd, 29862306a36Sopenharmony_ci "Congestion Control table size %d less than minimum %d for port %d\n", 29962306a36Sopenharmony_ci qib_cc_table_size, IB_CCT_MIN_ENTRIES, port); 30062306a36Sopenharmony_ci } 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci qib_dev_err(dd, "Congestion Control Agent disabled for port %d\n", 30362306a36Sopenharmony_ci port); 30462306a36Sopenharmony_ci return 0; 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic int init_pioavailregs(struct qib_devdata *dd) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci int ret, pidx; 31062306a36Sopenharmony_ci u64 *status_page; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci dd->pioavailregs_dma = dma_alloc_coherent( 31362306a36Sopenharmony_ci &dd->pcidev->dev, PAGE_SIZE, &dd->pioavailregs_phys, 31462306a36Sopenharmony_ci GFP_KERNEL); 31562306a36Sopenharmony_ci if (!dd->pioavailregs_dma) { 31662306a36Sopenharmony_ci qib_dev_err(dd, 31762306a36Sopenharmony_ci "failed to allocate PIOavail reg area in memory\n"); 31862306a36Sopenharmony_ci ret = -ENOMEM; 31962306a36Sopenharmony_ci goto done; 32062306a36Sopenharmony_ci } 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci /* 32362306a36Sopenharmony_ci * We really want L2 cache aligned, but for current CPUs of 32462306a36Sopenharmony_ci * interest, they are the same. 32562306a36Sopenharmony_ci */ 32662306a36Sopenharmony_ci status_page = (u64 *) 32762306a36Sopenharmony_ci ((char *) dd->pioavailregs_dma + 32862306a36Sopenharmony_ci ((2 * L1_CACHE_BYTES + 32962306a36Sopenharmony_ci dd->pioavregs * sizeof(u64)) & ~L1_CACHE_BYTES)); 33062306a36Sopenharmony_ci /* device status comes first, for backwards compatibility */ 33162306a36Sopenharmony_ci dd->devstatusp = status_page; 33262306a36Sopenharmony_ci *status_page++ = 0; 33362306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 33462306a36Sopenharmony_ci dd->pport[pidx].statusp = status_page; 33562306a36Sopenharmony_ci *status_page++ = 0; 33662306a36Sopenharmony_ci } 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci /* 33962306a36Sopenharmony_ci * Setup buffer to hold freeze and other messages, accessible to 34062306a36Sopenharmony_ci * apps, following statusp. This is per-unit, not per port. 34162306a36Sopenharmony_ci */ 34262306a36Sopenharmony_ci dd->freezemsg = (char *) status_page; 34362306a36Sopenharmony_ci *dd->freezemsg = 0; 34462306a36Sopenharmony_ci /* length of msg buffer is "whatever is left" */ 34562306a36Sopenharmony_ci ret = (char *) status_page - (char *) dd->pioavailregs_dma; 34662306a36Sopenharmony_ci dd->freezelen = PAGE_SIZE - ret; 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci ret = 0; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_cidone: 35162306a36Sopenharmony_ci return ret; 35262306a36Sopenharmony_ci} 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci/** 35562306a36Sopenharmony_ci * init_shadow_tids - allocate the shadow TID array 35662306a36Sopenharmony_ci * @dd: the qlogic_ib device 35762306a36Sopenharmony_ci * 35862306a36Sopenharmony_ci * allocate the shadow TID array, so we can qib_munlock previous 35962306a36Sopenharmony_ci * entries. It may make more sense to move the pageshadow to the 36062306a36Sopenharmony_ci * ctxt data structure, so we only allocate memory for ctxts actually 36162306a36Sopenharmony_ci * in use, since we at 8k per ctxt, now. 36262306a36Sopenharmony_ci * We don't want failures here to prevent use of the driver/chip, 36362306a36Sopenharmony_ci * so no return value. 36462306a36Sopenharmony_ci */ 36562306a36Sopenharmony_cistatic void init_shadow_tids(struct qib_devdata *dd) 36662306a36Sopenharmony_ci{ 36762306a36Sopenharmony_ci struct page **pages; 36862306a36Sopenharmony_ci dma_addr_t *addrs; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci pages = vzalloc(array_size(sizeof(struct page *), 37162306a36Sopenharmony_ci dd->cfgctxts * dd->rcvtidcnt)); 37262306a36Sopenharmony_ci if (!pages) 37362306a36Sopenharmony_ci goto bail; 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci addrs = vzalloc(array_size(sizeof(dma_addr_t), 37662306a36Sopenharmony_ci dd->cfgctxts * dd->rcvtidcnt)); 37762306a36Sopenharmony_ci if (!addrs) 37862306a36Sopenharmony_ci goto bail_free; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci dd->pageshadow = pages; 38162306a36Sopenharmony_ci dd->physshadow = addrs; 38262306a36Sopenharmony_ci return; 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_cibail_free: 38562306a36Sopenharmony_ci vfree(pages); 38662306a36Sopenharmony_cibail: 38762306a36Sopenharmony_ci dd->pageshadow = NULL; 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci/* 39162306a36Sopenharmony_ci * Do initialization for device that is only needed on 39262306a36Sopenharmony_ci * first detect, not on resets. 39362306a36Sopenharmony_ci */ 39462306a36Sopenharmony_cistatic int loadtime_init(struct qib_devdata *dd) 39562306a36Sopenharmony_ci{ 39662306a36Sopenharmony_ci int ret = 0; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci if (((dd->revision >> QLOGIC_IB_R_SOFTWARE_SHIFT) & 39962306a36Sopenharmony_ci QLOGIC_IB_R_SOFTWARE_MASK) != QIB_CHIP_SWVERSION) { 40062306a36Sopenharmony_ci qib_dev_err(dd, 40162306a36Sopenharmony_ci "Driver only handles version %d, chip swversion is %d (%llx), failing\n", 40262306a36Sopenharmony_ci QIB_CHIP_SWVERSION, 40362306a36Sopenharmony_ci (int)(dd->revision >> 40462306a36Sopenharmony_ci QLOGIC_IB_R_SOFTWARE_SHIFT) & 40562306a36Sopenharmony_ci QLOGIC_IB_R_SOFTWARE_MASK, 40662306a36Sopenharmony_ci (unsigned long long) dd->revision); 40762306a36Sopenharmony_ci ret = -ENOSYS; 40862306a36Sopenharmony_ci goto done; 40962306a36Sopenharmony_ci } 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci if (dd->revision & QLOGIC_IB_R_EMULATOR_MASK) 41262306a36Sopenharmony_ci qib_devinfo(dd->pcidev, "%s", dd->boardversion); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci spin_lock_init(&dd->pioavail_lock); 41562306a36Sopenharmony_ci spin_lock_init(&dd->sendctrl_lock); 41662306a36Sopenharmony_ci spin_lock_init(&dd->uctxt_lock); 41762306a36Sopenharmony_ci spin_lock_init(&dd->qib_diag_trans_lock); 41862306a36Sopenharmony_ci spin_lock_init(&dd->eep_st_lock); 41962306a36Sopenharmony_ci mutex_init(&dd->eep_lock); 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci if (qib_mini_init) 42262306a36Sopenharmony_ci goto done; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci ret = init_pioavailregs(dd); 42562306a36Sopenharmony_ci init_shadow_tids(dd); 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci qib_get_eeprom_info(dd); 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci /* setup time (don't start yet) to verify we got interrupt */ 43062306a36Sopenharmony_ci timer_setup(&dd->intrchk_timer, verify_interrupt, 0); 43162306a36Sopenharmony_cidone: 43262306a36Sopenharmony_ci return ret; 43362306a36Sopenharmony_ci} 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci/** 43662306a36Sopenharmony_ci * init_after_reset - re-initialize after a reset 43762306a36Sopenharmony_ci * @dd: the qlogic_ib device 43862306a36Sopenharmony_ci * 43962306a36Sopenharmony_ci * sanity check at least some of the values after reset, and 44062306a36Sopenharmony_ci * ensure no receive or transmit (explicitly, in case reset 44162306a36Sopenharmony_ci * failed 44262306a36Sopenharmony_ci */ 44362306a36Sopenharmony_cistatic int init_after_reset(struct qib_devdata *dd) 44462306a36Sopenharmony_ci{ 44562306a36Sopenharmony_ci int i; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci /* 44862306a36Sopenharmony_ci * Ensure chip does no sends or receives, tail updates, or 44962306a36Sopenharmony_ci * pioavail updates while we re-initialize. This is mostly 45062306a36Sopenharmony_ci * for the driver data structures, not chip registers. 45162306a36Sopenharmony_ci */ 45262306a36Sopenharmony_ci for (i = 0; i < dd->num_pports; ++i) { 45362306a36Sopenharmony_ci /* 45462306a36Sopenharmony_ci * ctxt == -1 means "all contexts". Only really safe for 45562306a36Sopenharmony_ci * _dis_abling things, as here. 45662306a36Sopenharmony_ci */ 45762306a36Sopenharmony_ci dd->f_rcvctrl(dd->pport + i, QIB_RCVCTRL_CTXT_DIS | 45862306a36Sopenharmony_ci QIB_RCVCTRL_INTRAVAIL_DIS | 45962306a36Sopenharmony_ci QIB_RCVCTRL_TAILUPD_DIS, -1); 46062306a36Sopenharmony_ci /* Redundant across ports for some, but no big deal. */ 46162306a36Sopenharmony_ci dd->f_sendctrl(dd->pport + i, QIB_SENDCTRL_SEND_DIS | 46262306a36Sopenharmony_ci QIB_SENDCTRL_AVAIL_DIS); 46362306a36Sopenharmony_ci } 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci return 0; 46662306a36Sopenharmony_ci} 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_cistatic void enable_chip(struct qib_devdata *dd) 46962306a36Sopenharmony_ci{ 47062306a36Sopenharmony_ci u64 rcvmask; 47162306a36Sopenharmony_ci int i; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci /* 47462306a36Sopenharmony_ci * Enable PIO send, and update of PIOavail regs to memory. 47562306a36Sopenharmony_ci */ 47662306a36Sopenharmony_ci for (i = 0; i < dd->num_pports; ++i) 47762306a36Sopenharmony_ci dd->f_sendctrl(dd->pport + i, QIB_SENDCTRL_SEND_ENB | 47862306a36Sopenharmony_ci QIB_SENDCTRL_AVAIL_ENB); 47962306a36Sopenharmony_ci /* 48062306a36Sopenharmony_ci * Enable kernel ctxts' receive and receive interrupt. 48162306a36Sopenharmony_ci * Other ctxts done as user opens and inits them. 48262306a36Sopenharmony_ci */ 48362306a36Sopenharmony_ci rcvmask = QIB_RCVCTRL_CTXT_ENB | QIB_RCVCTRL_INTRAVAIL_ENB; 48462306a36Sopenharmony_ci rcvmask |= (dd->flags & QIB_NODMA_RTAIL) ? 48562306a36Sopenharmony_ci QIB_RCVCTRL_TAILUPD_DIS : QIB_RCVCTRL_TAILUPD_ENB; 48662306a36Sopenharmony_ci for (i = 0; dd->rcd && i < dd->first_user_ctxt; ++i) { 48762306a36Sopenharmony_ci struct qib_ctxtdata *rcd = dd->rcd[i]; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci if (rcd) 49062306a36Sopenharmony_ci dd->f_rcvctrl(rcd->ppd, rcvmask, i); 49162306a36Sopenharmony_ci } 49262306a36Sopenharmony_ci} 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_cistatic void verify_interrupt(struct timer_list *t) 49562306a36Sopenharmony_ci{ 49662306a36Sopenharmony_ci struct qib_devdata *dd = from_timer(dd, t, intrchk_timer); 49762306a36Sopenharmony_ci u64 int_counter; 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci if (!dd) 50062306a36Sopenharmony_ci return; /* being torn down */ 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci /* 50362306a36Sopenharmony_ci * If we don't have a lid or any interrupts, let the user know and 50462306a36Sopenharmony_ci * don't bother checking again. 50562306a36Sopenharmony_ci */ 50662306a36Sopenharmony_ci int_counter = qib_int_counter(dd) - dd->z_int_counter; 50762306a36Sopenharmony_ci if (int_counter == 0) { 50862306a36Sopenharmony_ci if (!dd->f_intr_fallback(dd)) 50962306a36Sopenharmony_ci dev_err(&dd->pcidev->dev, 51062306a36Sopenharmony_ci "No interrupts detected, not usable.\n"); 51162306a36Sopenharmony_ci else /* re-arm the timer to see if fallback works */ 51262306a36Sopenharmony_ci mod_timer(&dd->intrchk_timer, jiffies + HZ/2); 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ci} 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_cistatic void init_piobuf_state(struct qib_devdata *dd) 51762306a36Sopenharmony_ci{ 51862306a36Sopenharmony_ci int i, pidx; 51962306a36Sopenharmony_ci u32 uctxts; 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci /* 52262306a36Sopenharmony_ci * Ensure all buffers are free, and fifos empty. Buffers 52362306a36Sopenharmony_ci * are common, so only do once for port 0. 52462306a36Sopenharmony_ci * 52562306a36Sopenharmony_ci * After enable and qib_chg_pioavailkernel so we can safely 52662306a36Sopenharmony_ci * enable pioavail updates and PIOENABLE. After this, packets 52762306a36Sopenharmony_ci * are ready and able to go out. 52862306a36Sopenharmony_ci */ 52962306a36Sopenharmony_ci dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_ALL); 53062306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) 53162306a36Sopenharmony_ci dd->f_sendctrl(dd->pport + pidx, QIB_SENDCTRL_FLUSH); 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci /* 53462306a36Sopenharmony_ci * If not all sendbufs are used, add the one to each of the lower 53562306a36Sopenharmony_ci * numbered contexts. pbufsctxt and lastctxt_piobuf are 53662306a36Sopenharmony_ci * calculated in chip-specific code because it may cause some 53762306a36Sopenharmony_ci * chip-specific adjustments to be made. 53862306a36Sopenharmony_ci */ 53962306a36Sopenharmony_ci uctxts = dd->cfgctxts - dd->first_user_ctxt; 54062306a36Sopenharmony_ci dd->ctxts_extrabuf = dd->pbufsctxt ? 54162306a36Sopenharmony_ci dd->lastctxt_piobuf - (dd->pbufsctxt * uctxts) : 0; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci /* 54462306a36Sopenharmony_ci * Set up the shadow copies of the piobufavail registers, 54562306a36Sopenharmony_ci * which we compare against the chip registers for now, and 54662306a36Sopenharmony_ci * the in memory DMA'ed copies of the registers. 54762306a36Sopenharmony_ci * By now pioavail updates to memory should have occurred, so 54862306a36Sopenharmony_ci * copy them into our working/shadow registers; this is in 54962306a36Sopenharmony_ci * case something went wrong with abort, but mostly to get the 55062306a36Sopenharmony_ci * initial values of the generation bit correct. 55162306a36Sopenharmony_ci */ 55262306a36Sopenharmony_ci for (i = 0; i < dd->pioavregs; i++) { 55362306a36Sopenharmony_ci __le64 tmp; 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci tmp = dd->pioavailregs_dma[i]; 55662306a36Sopenharmony_ci /* 55762306a36Sopenharmony_ci * Don't need to worry about pioavailkernel here 55862306a36Sopenharmony_ci * because we will call qib_chg_pioavailkernel() later 55962306a36Sopenharmony_ci * in initialization, to busy out buffers as needed. 56062306a36Sopenharmony_ci */ 56162306a36Sopenharmony_ci dd->pioavailshadow[i] = le64_to_cpu(tmp); 56262306a36Sopenharmony_ci } 56362306a36Sopenharmony_ci while (i < ARRAY_SIZE(dd->pioavailshadow)) 56462306a36Sopenharmony_ci dd->pioavailshadow[i++] = 0; /* for debugging sanity */ 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci /* after pioavailshadow is setup */ 56762306a36Sopenharmony_ci qib_chg_pioavailkernel(dd, 0, dd->piobcnt2k + dd->piobcnt4k, 56862306a36Sopenharmony_ci TXCHK_CHG_TYPE_KERN, NULL); 56962306a36Sopenharmony_ci dd->f_initvl15_bufs(dd); 57062306a36Sopenharmony_ci} 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci/** 57362306a36Sopenharmony_ci * qib_create_workqueues - create per port workqueues 57462306a36Sopenharmony_ci * @dd: the qlogic_ib device 57562306a36Sopenharmony_ci */ 57662306a36Sopenharmony_cistatic int qib_create_workqueues(struct qib_devdata *dd) 57762306a36Sopenharmony_ci{ 57862306a36Sopenharmony_ci int pidx; 57962306a36Sopenharmony_ci struct qib_pportdata *ppd; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 58262306a36Sopenharmony_ci ppd = dd->pport + pidx; 58362306a36Sopenharmony_ci if (!ppd->qib_wq) { 58462306a36Sopenharmony_ci char wq_name[8]; /* 3 + 2 + 1 + 1 + 1 */ 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci snprintf(wq_name, sizeof(wq_name), "qib%d_%d", 58762306a36Sopenharmony_ci dd->unit, pidx); 58862306a36Sopenharmony_ci ppd->qib_wq = alloc_ordered_workqueue(wq_name, 58962306a36Sopenharmony_ci WQ_MEM_RECLAIM); 59062306a36Sopenharmony_ci if (!ppd->qib_wq) 59162306a36Sopenharmony_ci goto wq_error; 59262306a36Sopenharmony_ci } 59362306a36Sopenharmony_ci } 59462306a36Sopenharmony_ci return 0; 59562306a36Sopenharmony_ciwq_error: 59662306a36Sopenharmony_ci pr_err("create_singlethread_workqueue failed for port %d\n", 59762306a36Sopenharmony_ci pidx + 1); 59862306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 59962306a36Sopenharmony_ci ppd = dd->pport + pidx; 60062306a36Sopenharmony_ci if (ppd->qib_wq) { 60162306a36Sopenharmony_ci destroy_workqueue(ppd->qib_wq); 60262306a36Sopenharmony_ci ppd->qib_wq = NULL; 60362306a36Sopenharmony_ci } 60462306a36Sopenharmony_ci } 60562306a36Sopenharmony_ci return -ENOMEM; 60662306a36Sopenharmony_ci} 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_cistatic void qib_free_pportdata(struct qib_pportdata *ppd) 60962306a36Sopenharmony_ci{ 61062306a36Sopenharmony_ci free_percpu(ppd->ibport_data.pmastats); 61162306a36Sopenharmony_ci free_percpu(ppd->ibport_data.rvp.rc_acks); 61262306a36Sopenharmony_ci free_percpu(ppd->ibport_data.rvp.rc_qacks); 61362306a36Sopenharmony_ci free_percpu(ppd->ibport_data.rvp.rc_delayed_comp); 61462306a36Sopenharmony_ci ppd->ibport_data.pmastats = NULL; 61562306a36Sopenharmony_ci} 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci/** 61862306a36Sopenharmony_ci * qib_init - do the actual initialization sequence on the chip 61962306a36Sopenharmony_ci * @dd: the qlogic_ib device 62062306a36Sopenharmony_ci * @reinit: reinitializing, so don't allocate new memory 62162306a36Sopenharmony_ci * 62262306a36Sopenharmony_ci * Do the actual initialization sequence on the chip. This is done 62362306a36Sopenharmony_ci * both from the init routine called from the PCI infrastructure, and 62462306a36Sopenharmony_ci * when we reset the chip, or detect that it was reset internally, 62562306a36Sopenharmony_ci * or it's administratively re-enabled. 62662306a36Sopenharmony_ci * 62762306a36Sopenharmony_ci * Memory allocation here and in called routines is only done in 62862306a36Sopenharmony_ci * the first case (reinit == 0). We have to be careful, because even 62962306a36Sopenharmony_ci * without memory allocation, we need to re-write all the chip registers 63062306a36Sopenharmony_ci * TIDs, etc. after the reset or enable has completed. 63162306a36Sopenharmony_ci */ 63262306a36Sopenharmony_ciint qib_init(struct qib_devdata *dd, int reinit) 63362306a36Sopenharmony_ci{ 63462306a36Sopenharmony_ci int ret = 0, pidx, lastfail = 0; 63562306a36Sopenharmony_ci u32 portok = 0; 63662306a36Sopenharmony_ci unsigned i; 63762306a36Sopenharmony_ci struct qib_ctxtdata *rcd; 63862306a36Sopenharmony_ci struct qib_pportdata *ppd; 63962306a36Sopenharmony_ci unsigned long flags; 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci /* Set linkstate to unknown, so we can watch for a transition. */ 64262306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 64362306a36Sopenharmony_ci ppd = dd->pport + pidx; 64462306a36Sopenharmony_ci spin_lock_irqsave(&ppd->lflags_lock, flags); 64562306a36Sopenharmony_ci ppd->lflags &= ~(QIBL_LINKACTIVE | QIBL_LINKARMED | 64662306a36Sopenharmony_ci QIBL_LINKDOWN | QIBL_LINKINIT | 64762306a36Sopenharmony_ci QIBL_LINKV); 64862306a36Sopenharmony_ci spin_unlock_irqrestore(&ppd->lflags_lock, flags); 64962306a36Sopenharmony_ci } 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci if (reinit) 65262306a36Sopenharmony_ci ret = init_after_reset(dd); 65362306a36Sopenharmony_ci else 65462306a36Sopenharmony_ci ret = loadtime_init(dd); 65562306a36Sopenharmony_ci if (ret) 65662306a36Sopenharmony_ci goto done; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci /* Bypass most chip-init, to get to device creation */ 65962306a36Sopenharmony_ci if (qib_mini_init) 66062306a36Sopenharmony_ci return 0; 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci ret = dd->f_late_initreg(dd); 66362306a36Sopenharmony_ci if (ret) 66462306a36Sopenharmony_ci goto done; 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci /* dd->rcd can be NULL if early init failed */ 66762306a36Sopenharmony_ci for (i = 0; dd->rcd && i < dd->first_user_ctxt; ++i) { 66862306a36Sopenharmony_ci /* 66962306a36Sopenharmony_ci * Set up the (kernel) rcvhdr queue and egr TIDs. If doing 67062306a36Sopenharmony_ci * re-init, the simplest way to handle this is to free 67162306a36Sopenharmony_ci * existing, and re-allocate. 67262306a36Sopenharmony_ci * Need to re-create rest of ctxt 0 ctxtdata as well. 67362306a36Sopenharmony_ci */ 67462306a36Sopenharmony_ci rcd = dd->rcd[i]; 67562306a36Sopenharmony_ci if (!rcd) 67662306a36Sopenharmony_ci continue; 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci lastfail = qib_create_rcvhdrq(dd, rcd); 67962306a36Sopenharmony_ci if (!lastfail) 68062306a36Sopenharmony_ci lastfail = qib_setup_eagerbufs(rcd); 68162306a36Sopenharmony_ci if (lastfail) 68262306a36Sopenharmony_ci qib_dev_err(dd, 68362306a36Sopenharmony_ci "failed to allocate kernel ctxt's rcvhdrq and/or egr bufs\n"); 68462306a36Sopenharmony_ci } 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 68762306a36Sopenharmony_ci int mtu; 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci if (lastfail) 69062306a36Sopenharmony_ci ret = lastfail; 69162306a36Sopenharmony_ci ppd = dd->pport + pidx; 69262306a36Sopenharmony_ci mtu = ib_mtu_enum_to_int(qib_ibmtu); 69362306a36Sopenharmony_ci if (mtu == -1) { 69462306a36Sopenharmony_ci mtu = QIB_DEFAULT_MTU; 69562306a36Sopenharmony_ci qib_ibmtu = 0; /* don't leave invalid value */ 69662306a36Sopenharmony_ci } 69762306a36Sopenharmony_ci /* set max we can ever have for this driver load */ 69862306a36Sopenharmony_ci ppd->init_ibmaxlen = min(mtu > 2048 ? 69962306a36Sopenharmony_ci dd->piosize4k : dd->piosize2k, 70062306a36Sopenharmony_ci dd->rcvegrbufsize + 70162306a36Sopenharmony_ci (dd->rcvhdrentsize << 2)); 70262306a36Sopenharmony_ci /* 70362306a36Sopenharmony_ci * Have to initialize ibmaxlen, but this will normally 70462306a36Sopenharmony_ci * change immediately in qib_set_mtu(). 70562306a36Sopenharmony_ci */ 70662306a36Sopenharmony_ci ppd->ibmaxlen = ppd->init_ibmaxlen; 70762306a36Sopenharmony_ci qib_set_mtu(ppd, mtu); 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci spin_lock_irqsave(&ppd->lflags_lock, flags); 71062306a36Sopenharmony_ci ppd->lflags |= QIBL_IB_LINK_DISABLED; 71162306a36Sopenharmony_ci spin_unlock_irqrestore(&ppd->lflags_lock, flags); 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci lastfail = dd->f_bringup_serdes(ppd); 71462306a36Sopenharmony_ci if (lastfail) { 71562306a36Sopenharmony_ci qib_devinfo(dd->pcidev, 71662306a36Sopenharmony_ci "Failed to bringup IB port %u\n", ppd->port); 71762306a36Sopenharmony_ci lastfail = -ENETDOWN; 71862306a36Sopenharmony_ci continue; 71962306a36Sopenharmony_ci } 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci portok++; 72262306a36Sopenharmony_ci } 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci if (!portok) { 72562306a36Sopenharmony_ci /* none of the ports initialized */ 72662306a36Sopenharmony_ci if (!ret && lastfail) 72762306a36Sopenharmony_ci ret = lastfail; 72862306a36Sopenharmony_ci else if (!ret) 72962306a36Sopenharmony_ci ret = -ENETDOWN; 73062306a36Sopenharmony_ci /* but continue on, so we can debug cause */ 73162306a36Sopenharmony_ci } 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_ci enable_chip(dd); 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci init_piobuf_state(dd); 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_cidone: 73862306a36Sopenharmony_ci if (!ret) { 73962306a36Sopenharmony_ci /* chip is OK for user apps; mark it as initialized */ 74062306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 74162306a36Sopenharmony_ci ppd = dd->pport + pidx; 74262306a36Sopenharmony_ci /* 74362306a36Sopenharmony_ci * Set status even if port serdes is not initialized 74462306a36Sopenharmony_ci * so that diags will work. 74562306a36Sopenharmony_ci */ 74662306a36Sopenharmony_ci *ppd->statusp |= QIB_STATUS_CHIP_PRESENT | 74762306a36Sopenharmony_ci QIB_STATUS_INITTED; 74862306a36Sopenharmony_ci if (!ppd->link_speed_enabled) 74962306a36Sopenharmony_ci continue; 75062306a36Sopenharmony_ci if (dd->flags & QIB_HAS_SEND_DMA) 75162306a36Sopenharmony_ci ret = qib_setup_sdma(ppd); 75262306a36Sopenharmony_ci timer_setup(&ppd->hol_timer, qib_hol_event, 0); 75362306a36Sopenharmony_ci ppd->hol_state = QIB_HOL_UP; 75462306a36Sopenharmony_ci } 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci /* now we can enable all interrupts from the chip */ 75762306a36Sopenharmony_ci dd->f_set_intr_state(dd, 1); 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci /* 76062306a36Sopenharmony_ci * Setup to verify we get an interrupt, and fallback 76162306a36Sopenharmony_ci * to an alternate if necessary and possible. 76262306a36Sopenharmony_ci */ 76362306a36Sopenharmony_ci mod_timer(&dd->intrchk_timer, jiffies + HZ/2); 76462306a36Sopenharmony_ci /* start stats retrieval timer */ 76562306a36Sopenharmony_ci mod_timer(&dd->stats_timer, jiffies + HZ * ACTIVITY_TIMER); 76662306a36Sopenharmony_ci } 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci /* if ret is non-zero, we probably should do some cleanup here... */ 76962306a36Sopenharmony_ci return ret; 77062306a36Sopenharmony_ci} 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_ci/* 77362306a36Sopenharmony_ci * These next two routines are placeholders in case we don't have per-arch 77462306a36Sopenharmony_ci * code for controlling write combining. If explicit control of write 77562306a36Sopenharmony_ci * combining is not available, performance will probably be awful. 77662306a36Sopenharmony_ci */ 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ciint __attribute__((weak)) qib_enable_wc(struct qib_devdata *dd) 77962306a36Sopenharmony_ci{ 78062306a36Sopenharmony_ci return -EOPNOTSUPP; 78162306a36Sopenharmony_ci} 78262306a36Sopenharmony_ci 78362306a36Sopenharmony_civoid __attribute__((weak)) qib_disable_wc(struct qib_devdata *dd) 78462306a36Sopenharmony_ci{ 78562306a36Sopenharmony_ci} 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_cistruct qib_devdata *qib_lookup(int unit) 78862306a36Sopenharmony_ci{ 78962306a36Sopenharmony_ci return xa_load(&qib_dev_table, unit); 79062306a36Sopenharmony_ci} 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci/* 79362306a36Sopenharmony_ci * Stop the timers during unit shutdown, or after an error late 79462306a36Sopenharmony_ci * in initialization. 79562306a36Sopenharmony_ci */ 79662306a36Sopenharmony_cistatic void qib_stop_timers(struct qib_devdata *dd) 79762306a36Sopenharmony_ci{ 79862306a36Sopenharmony_ci struct qib_pportdata *ppd; 79962306a36Sopenharmony_ci int pidx; 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci if (dd->stats_timer.function) 80262306a36Sopenharmony_ci del_timer_sync(&dd->stats_timer); 80362306a36Sopenharmony_ci if (dd->intrchk_timer.function) 80462306a36Sopenharmony_ci del_timer_sync(&dd->intrchk_timer); 80562306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 80662306a36Sopenharmony_ci ppd = dd->pport + pidx; 80762306a36Sopenharmony_ci if (ppd->hol_timer.function) 80862306a36Sopenharmony_ci del_timer_sync(&ppd->hol_timer); 80962306a36Sopenharmony_ci if (ppd->led_override_timer.function) { 81062306a36Sopenharmony_ci del_timer_sync(&ppd->led_override_timer); 81162306a36Sopenharmony_ci atomic_set(&ppd->led_override_timer_active, 0); 81262306a36Sopenharmony_ci } 81362306a36Sopenharmony_ci if (ppd->symerr_clear_timer.function) 81462306a36Sopenharmony_ci del_timer_sync(&ppd->symerr_clear_timer); 81562306a36Sopenharmony_ci } 81662306a36Sopenharmony_ci} 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci/** 81962306a36Sopenharmony_ci * qib_shutdown_device - shut down a device 82062306a36Sopenharmony_ci * @dd: the qlogic_ib device 82162306a36Sopenharmony_ci * 82262306a36Sopenharmony_ci * This is called to make the device quiet when we are about to 82362306a36Sopenharmony_ci * unload the driver, and also when the device is administratively 82462306a36Sopenharmony_ci * disabled. It does not free any data structures. 82562306a36Sopenharmony_ci * Everything it does has to be setup again by qib_init(dd, 1) 82662306a36Sopenharmony_ci */ 82762306a36Sopenharmony_cistatic void qib_shutdown_device(struct qib_devdata *dd) 82862306a36Sopenharmony_ci{ 82962306a36Sopenharmony_ci struct qib_pportdata *ppd; 83062306a36Sopenharmony_ci unsigned pidx; 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci if (dd->flags & QIB_SHUTDOWN) 83362306a36Sopenharmony_ci return; 83462306a36Sopenharmony_ci dd->flags |= QIB_SHUTDOWN; 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 83762306a36Sopenharmony_ci ppd = dd->pport + pidx; 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci spin_lock_irq(&ppd->lflags_lock); 84062306a36Sopenharmony_ci ppd->lflags &= ~(QIBL_LINKDOWN | QIBL_LINKINIT | 84162306a36Sopenharmony_ci QIBL_LINKARMED | QIBL_LINKACTIVE | 84262306a36Sopenharmony_ci QIBL_LINKV); 84362306a36Sopenharmony_ci spin_unlock_irq(&ppd->lflags_lock); 84462306a36Sopenharmony_ci *ppd->statusp &= ~(QIB_STATUS_IB_CONF | QIB_STATUS_IB_READY); 84562306a36Sopenharmony_ci } 84662306a36Sopenharmony_ci dd->flags &= ~QIB_INITTED; 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_ci /* mask interrupts, but not errors */ 84962306a36Sopenharmony_ci dd->f_set_intr_state(dd, 0); 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 85262306a36Sopenharmony_ci ppd = dd->pport + pidx; 85362306a36Sopenharmony_ci dd->f_rcvctrl(ppd, QIB_RCVCTRL_TAILUPD_DIS | 85462306a36Sopenharmony_ci QIB_RCVCTRL_CTXT_DIS | 85562306a36Sopenharmony_ci QIB_RCVCTRL_INTRAVAIL_DIS | 85662306a36Sopenharmony_ci QIB_RCVCTRL_PKEY_ENB, -1); 85762306a36Sopenharmony_ci /* 85862306a36Sopenharmony_ci * Gracefully stop all sends allowing any in progress to 85962306a36Sopenharmony_ci * trickle out first. 86062306a36Sopenharmony_ci */ 86162306a36Sopenharmony_ci dd->f_sendctrl(ppd, QIB_SENDCTRL_CLEAR); 86262306a36Sopenharmony_ci } 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci /* 86562306a36Sopenharmony_ci * Enough for anything that's going to trickle out to have actually 86662306a36Sopenharmony_ci * done so. 86762306a36Sopenharmony_ci */ 86862306a36Sopenharmony_ci udelay(20); 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 87162306a36Sopenharmony_ci ppd = dd->pport + pidx; 87262306a36Sopenharmony_ci dd->f_setextled(ppd, 0); /* make sure LEDs are off */ 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci if (dd->flags & QIB_HAS_SEND_DMA) 87562306a36Sopenharmony_ci qib_teardown_sdma(ppd); 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_ci dd->f_sendctrl(ppd, QIB_SENDCTRL_AVAIL_DIS | 87862306a36Sopenharmony_ci QIB_SENDCTRL_SEND_DIS); 87962306a36Sopenharmony_ci /* 88062306a36Sopenharmony_ci * Clear SerdesEnable. 88162306a36Sopenharmony_ci * We can't count on interrupts since we are stopping. 88262306a36Sopenharmony_ci */ 88362306a36Sopenharmony_ci dd->f_quiet_serdes(ppd); 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_ci if (ppd->qib_wq) { 88662306a36Sopenharmony_ci destroy_workqueue(ppd->qib_wq); 88762306a36Sopenharmony_ci ppd->qib_wq = NULL; 88862306a36Sopenharmony_ci } 88962306a36Sopenharmony_ci qib_free_pportdata(ppd); 89062306a36Sopenharmony_ci } 89162306a36Sopenharmony_ci 89262306a36Sopenharmony_ci} 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci/** 89562306a36Sopenharmony_ci * qib_free_ctxtdata - free a context's allocated data 89662306a36Sopenharmony_ci * @dd: the qlogic_ib device 89762306a36Sopenharmony_ci * @rcd: the ctxtdata structure 89862306a36Sopenharmony_ci * 89962306a36Sopenharmony_ci * free up any allocated data for a context 90062306a36Sopenharmony_ci * This should not touch anything that would affect a simultaneous 90162306a36Sopenharmony_ci * re-allocation of context data, because it is called after qib_mutex 90262306a36Sopenharmony_ci * is released (and can be called from reinit as well). 90362306a36Sopenharmony_ci * It should never change any chip state, or global driver state. 90462306a36Sopenharmony_ci */ 90562306a36Sopenharmony_civoid qib_free_ctxtdata(struct qib_devdata *dd, struct qib_ctxtdata *rcd) 90662306a36Sopenharmony_ci{ 90762306a36Sopenharmony_ci if (!rcd) 90862306a36Sopenharmony_ci return; 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_ci if (rcd->rcvhdrq) { 91162306a36Sopenharmony_ci dma_free_coherent(&dd->pcidev->dev, rcd->rcvhdrq_size, 91262306a36Sopenharmony_ci rcd->rcvhdrq, rcd->rcvhdrq_phys); 91362306a36Sopenharmony_ci rcd->rcvhdrq = NULL; 91462306a36Sopenharmony_ci if (rcd->rcvhdrtail_kvaddr) { 91562306a36Sopenharmony_ci dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE, 91662306a36Sopenharmony_ci rcd->rcvhdrtail_kvaddr, 91762306a36Sopenharmony_ci rcd->rcvhdrqtailaddr_phys); 91862306a36Sopenharmony_ci rcd->rcvhdrtail_kvaddr = NULL; 91962306a36Sopenharmony_ci } 92062306a36Sopenharmony_ci } 92162306a36Sopenharmony_ci if (rcd->rcvegrbuf) { 92262306a36Sopenharmony_ci unsigned e; 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci for (e = 0; e < rcd->rcvegrbuf_chunks; e++) { 92562306a36Sopenharmony_ci void *base = rcd->rcvegrbuf[e]; 92662306a36Sopenharmony_ci size_t size = rcd->rcvegrbuf_size; 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci dma_free_coherent(&dd->pcidev->dev, size, 92962306a36Sopenharmony_ci base, rcd->rcvegrbuf_phys[e]); 93062306a36Sopenharmony_ci } 93162306a36Sopenharmony_ci kfree(rcd->rcvegrbuf); 93262306a36Sopenharmony_ci rcd->rcvegrbuf = NULL; 93362306a36Sopenharmony_ci kfree(rcd->rcvegrbuf_phys); 93462306a36Sopenharmony_ci rcd->rcvegrbuf_phys = NULL; 93562306a36Sopenharmony_ci rcd->rcvegrbuf_chunks = 0; 93662306a36Sopenharmony_ci } 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci kfree(rcd->tid_pg_list); 93962306a36Sopenharmony_ci vfree(rcd->user_event_mask); 94062306a36Sopenharmony_ci vfree(rcd->subctxt_uregbase); 94162306a36Sopenharmony_ci vfree(rcd->subctxt_rcvegrbuf); 94262306a36Sopenharmony_ci vfree(rcd->subctxt_rcvhdr_base); 94362306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 94462306a36Sopenharmony_ci kfree(rcd->opstats); 94562306a36Sopenharmony_ci rcd->opstats = NULL; 94662306a36Sopenharmony_ci#endif 94762306a36Sopenharmony_ci kfree(rcd); 94862306a36Sopenharmony_ci} 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci/* 95162306a36Sopenharmony_ci * Perform a PIO buffer bandwidth write test, to verify proper system 95262306a36Sopenharmony_ci * configuration. Even when all the setup calls work, occasionally 95362306a36Sopenharmony_ci * BIOS or other issues can prevent write combining from working, or 95462306a36Sopenharmony_ci * can cause other bandwidth problems to the chip. 95562306a36Sopenharmony_ci * 95662306a36Sopenharmony_ci * This test simply writes the same buffer over and over again, and 95762306a36Sopenharmony_ci * measures close to the peak bandwidth to the chip (not testing 95862306a36Sopenharmony_ci * data bandwidth to the wire). On chips that use an address-based 95962306a36Sopenharmony_ci * trigger to send packets to the wire, this is easy. On chips that 96062306a36Sopenharmony_ci * use a count to trigger, we want to make sure that the packet doesn't 96162306a36Sopenharmony_ci * go out on the wire, or trigger flow control checks. 96262306a36Sopenharmony_ci */ 96362306a36Sopenharmony_cistatic void qib_verify_pioperf(struct qib_devdata *dd) 96462306a36Sopenharmony_ci{ 96562306a36Sopenharmony_ci u32 pbnum, cnt, lcnt; 96662306a36Sopenharmony_ci u32 __iomem *piobuf; 96762306a36Sopenharmony_ci u32 *addr; 96862306a36Sopenharmony_ci u64 msecs, emsecs; 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci piobuf = dd->f_getsendbuf(dd->pport, 0ULL, &pbnum); 97162306a36Sopenharmony_ci if (!piobuf) { 97262306a36Sopenharmony_ci qib_devinfo(dd->pcidev, 97362306a36Sopenharmony_ci "No PIObufs for checking perf, skipping\n"); 97462306a36Sopenharmony_ci return; 97562306a36Sopenharmony_ci } 97662306a36Sopenharmony_ci 97762306a36Sopenharmony_ci /* 97862306a36Sopenharmony_ci * Enough to give us a reasonable test, less than piobuf size, and 97962306a36Sopenharmony_ci * likely multiple of store buffer length. 98062306a36Sopenharmony_ci */ 98162306a36Sopenharmony_ci cnt = 1024; 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci addr = vmalloc(cnt); 98462306a36Sopenharmony_ci if (!addr) 98562306a36Sopenharmony_ci goto done; 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci preempt_disable(); /* we want reasonably accurate elapsed time */ 98862306a36Sopenharmony_ci msecs = 1 + jiffies_to_msecs(jiffies); 98962306a36Sopenharmony_ci for (lcnt = 0; lcnt < 10000U; lcnt++) { 99062306a36Sopenharmony_ci /* wait until we cross msec boundary */ 99162306a36Sopenharmony_ci if (jiffies_to_msecs(jiffies) >= msecs) 99262306a36Sopenharmony_ci break; 99362306a36Sopenharmony_ci udelay(1); 99462306a36Sopenharmony_ci } 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ci dd->f_set_armlaunch(dd, 0); 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_ci /* 99962306a36Sopenharmony_ci * length 0, no dwords actually sent 100062306a36Sopenharmony_ci */ 100162306a36Sopenharmony_ci writeq(0, piobuf); 100262306a36Sopenharmony_ci qib_flush_wc(); 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci /* 100562306a36Sopenharmony_ci * This is only roughly accurate, since even with preempt we 100662306a36Sopenharmony_ci * still take interrupts that could take a while. Running for 100762306a36Sopenharmony_ci * >= 5 msec seems to get us "close enough" to accurate values. 100862306a36Sopenharmony_ci */ 100962306a36Sopenharmony_ci msecs = jiffies_to_msecs(jiffies); 101062306a36Sopenharmony_ci for (emsecs = lcnt = 0; emsecs <= 5UL; lcnt++) { 101162306a36Sopenharmony_ci qib_pio_copy(piobuf + 64, addr, cnt >> 2); 101262306a36Sopenharmony_ci emsecs = jiffies_to_msecs(jiffies) - msecs; 101362306a36Sopenharmony_ci } 101462306a36Sopenharmony_ci 101562306a36Sopenharmony_ci /* 1 GiB/sec, slightly over IB SDR line rate */ 101662306a36Sopenharmony_ci if (lcnt < (emsecs * 1024U)) 101762306a36Sopenharmony_ci qib_dev_err(dd, 101862306a36Sopenharmony_ci "Performance problem: bandwidth to PIO buffers is only %u MiB/sec\n", 101962306a36Sopenharmony_ci lcnt / (u32) emsecs); 102062306a36Sopenharmony_ci 102162306a36Sopenharmony_ci preempt_enable(); 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci vfree(addr); 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_cidone: 102662306a36Sopenharmony_ci /* disarm piobuf, so it's available again */ 102762306a36Sopenharmony_ci dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_BUF(pbnum)); 102862306a36Sopenharmony_ci qib_sendbuf_done(dd, pbnum); 102962306a36Sopenharmony_ci dd->f_set_armlaunch(dd, 1); 103062306a36Sopenharmony_ci} 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_civoid qib_free_devdata(struct qib_devdata *dd) 103362306a36Sopenharmony_ci{ 103462306a36Sopenharmony_ci unsigned long flags; 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci xa_lock_irqsave(&qib_dev_table, flags); 103762306a36Sopenharmony_ci __xa_erase(&qib_dev_table, dd->unit); 103862306a36Sopenharmony_ci xa_unlock_irqrestore(&qib_dev_table, flags); 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 104162306a36Sopenharmony_ci qib_dbg_ibdev_exit(&dd->verbs_dev); 104262306a36Sopenharmony_ci#endif 104362306a36Sopenharmony_ci free_percpu(dd->int_counter); 104462306a36Sopenharmony_ci rvt_dealloc_device(&dd->verbs_dev.rdi); 104562306a36Sopenharmony_ci} 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ciu64 qib_int_counter(struct qib_devdata *dd) 104862306a36Sopenharmony_ci{ 104962306a36Sopenharmony_ci int cpu; 105062306a36Sopenharmony_ci u64 int_counter = 0; 105162306a36Sopenharmony_ci 105262306a36Sopenharmony_ci for_each_possible_cpu(cpu) 105362306a36Sopenharmony_ci int_counter += *per_cpu_ptr(dd->int_counter, cpu); 105462306a36Sopenharmony_ci return int_counter; 105562306a36Sopenharmony_ci} 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_ciu64 qib_sps_ints(void) 105862306a36Sopenharmony_ci{ 105962306a36Sopenharmony_ci unsigned long index, flags; 106062306a36Sopenharmony_ci struct qib_devdata *dd; 106162306a36Sopenharmony_ci u64 sps_ints = 0; 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_ci xa_lock_irqsave(&qib_dev_table, flags); 106462306a36Sopenharmony_ci xa_for_each(&qib_dev_table, index, dd) { 106562306a36Sopenharmony_ci sps_ints += qib_int_counter(dd); 106662306a36Sopenharmony_ci } 106762306a36Sopenharmony_ci xa_unlock_irqrestore(&qib_dev_table, flags); 106862306a36Sopenharmony_ci return sps_ints; 106962306a36Sopenharmony_ci} 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci/* 107262306a36Sopenharmony_ci * Allocate our primary per-unit data structure. Must be done via verbs 107362306a36Sopenharmony_ci * allocator, because the verbs cleanup process both does cleanup and 107462306a36Sopenharmony_ci * free of the data structure. 107562306a36Sopenharmony_ci * "extra" is for chip-specific data. 107662306a36Sopenharmony_ci */ 107762306a36Sopenharmony_cistruct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra) 107862306a36Sopenharmony_ci{ 107962306a36Sopenharmony_ci struct qib_devdata *dd; 108062306a36Sopenharmony_ci int ret, nports; 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci /* extra is * number of ports */ 108362306a36Sopenharmony_ci nports = extra / sizeof(struct qib_pportdata); 108462306a36Sopenharmony_ci dd = (struct qib_devdata *)rvt_alloc_device(sizeof(*dd) + extra, 108562306a36Sopenharmony_ci nports); 108662306a36Sopenharmony_ci if (!dd) 108762306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 108862306a36Sopenharmony_ci 108962306a36Sopenharmony_ci ret = xa_alloc_irq(&qib_dev_table, &dd->unit, dd, xa_limit_32b, 109062306a36Sopenharmony_ci GFP_KERNEL); 109162306a36Sopenharmony_ci if (ret < 0) { 109262306a36Sopenharmony_ci qib_early_err(&pdev->dev, 109362306a36Sopenharmony_ci "Could not allocate unit ID: error %d\n", -ret); 109462306a36Sopenharmony_ci goto bail; 109562306a36Sopenharmony_ci } 109662306a36Sopenharmony_ci rvt_set_ibdev_name(&dd->verbs_dev.rdi, "%s%d", "qib", dd->unit); 109762306a36Sopenharmony_ci 109862306a36Sopenharmony_ci dd->int_counter = alloc_percpu(u64); 109962306a36Sopenharmony_ci if (!dd->int_counter) { 110062306a36Sopenharmony_ci ret = -ENOMEM; 110162306a36Sopenharmony_ci qib_early_err(&pdev->dev, 110262306a36Sopenharmony_ci "Could not allocate per-cpu int_counter\n"); 110362306a36Sopenharmony_ci goto bail; 110462306a36Sopenharmony_ci } 110562306a36Sopenharmony_ci 110662306a36Sopenharmony_ci if (!qib_cpulist_count) { 110762306a36Sopenharmony_ci u32 count = num_online_cpus(); 110862306a36Sopenharmony_ci 110962306a36Sopenharmony_ci qib_cpulist = bitmap_zalloc(count, GFP_KERNEL); 111062306a36Sopenharmony_ci if (qib_cpulist) 111162306a36Sopenharmony_ci qib_cpulist_count = count; 111262306a36Sopenharmony_ci } 111362306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 111462306a36Sopenharmony_ci qib_dbg_ibdev_init(&dd->verbs_dev); 111562306a36Sopenharmony_ci#endif 111662306a36Sopenharmony_ci return dd; 111762306a36Sopenharmony_cibail: 111862306a36Sopenharmony_ci if (!list_empty(&dd->list)) 111962306a36Sopenharmony_ci list_del_init(&dd->list); 112062306a36Sopenharmony_ci rvt_dealloc_device(&dd->verbs_dev.rdi); 112162306a36Sopenharmony_ci return ERR_PTR(ret); 112262306a36Sopenharmony_ci} 112362306a36Sopenharmony_ci 112462306a36Sopenharmony_ci/* 112562306a36Sopenharmony_ci * Called from freeze mode handlers, and from PCI error 112662306a36Sopenharmony_ci * reporting code. Should be paranoid about state of 112762306a36Sopenharmony_ci * system and data structures. 112862306a36Sopenharmony_ci */ 112962306a36Sopenharmony_civoid qib_disable_after_error(struct qib_devdata *dd) 113062306a36Sopenharmony_ci{ 113162306a36Sopenharmony_ci if (dd->flags & QIB_INITTED) { 113262306a36Sopenharmony_ci u32 pidx; 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_ci dd->flags &= ~QIB_INITTED; 113562306a36Sopenharmony_ci if (dd->pport) 113662306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 113762306a36Sopenharmony_ci struct qib_pportdata *ppd; 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_ci ppd = dd->pport + pidx; 114062306a36Sopenharmony_ci if (dd->flags & QIB_PRESENT) { 114162306a36Sopenharmony_ci qib_set_linkstate(ppd, 114262306a36Sopenharmony_ci QIB_IB_LINKDOWN_DISABLE); 114362306a36Sopenharmony_ci dd->f_setextled(ppd, 0); 114462306a36Sopenharmony_ci } 114562306a36Sopenharmony_ci *ppd->statusp &= ~QIB_STATUS_IB_READY; 114662306a36Sopenharmony_ci } 114762306a36Sopenharmony_ci } 114862306a36Sopenharmony_ci 114962306a36Sopenharmony_ci /* 115062306a36Sopenharmony_ci * Mark as having had an error for driver, and also 115162306a36Sopenharmony_ci * for /sys and status word mapped to user programs. 115262306a36Sopenharmony_ci * This marks unit as not usable, until reset. 115362306a36Sopenharmony_ci */ 115462306a36Sopenharmony_ci if (dd->devstatusp) 115562306a36Sopenharmony_ci *dd->devstatusp |= QIB_STATUS_HWERROR; 115662306a36Sopenharmony_ci} 115762306a36Sopenharmony_ci 115862306a36Sopenharmony_cistatic void qib_remove_one(struct pci_dev *); 115962306a36Sopenharmony_cistatic int qib_init_one(struct pci_dev *, const struct pci_device_id *); 116062306a36Sopenharmony_cistatic void qib_shutdown_one(struct pci_dev *); 116162306a36Sopenharmony_ci 116262306a36Sopenharmony_ci#define DRIVER_LOAD_MSG "Intel " QIB_DRV_NAME " loaded: " 116362306a36Sopenharmony_ci#define PFX QIB_DRV_NAME ": " 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_cistatic const struct pci_device_id qib_pci_tbl[] = { 116662306a36Sopenharmony_ci { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_QLOGIC_IB_6120) }, 116762306a36Sopenharmony_ci { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_IB_7220) }, 116862306a36Sopenharmony_ci { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_IB_7322) }, 116962306a36Sopenharmony_ci { 0, } 117062306a36Sopenharmony_ci}; 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, qib_pci_tbl); 117362306a36Sopenharmony_ci 117462306a36Sopenharmony_cistatic struct pci_driver qib_driver = { 117562306a36Sopenharmony_ci .name = QIB_DRV_NAME, 117662306a36Sopenharmony_ci .probe = qib_init_one, 117762306a36Sopenharmony_ci .remove = qib_remove_one, 117862306a36Sopenharmony_ci .shutdown = qib_shutdown_one, 117962306a36Sopenharmony_ci .id_table = qib_pci_tbl, 118062306a36Sopenharmony_ci .err_handler = &qib_pci_err_handler, 118162306a36Sopenharmony_ci}; 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_QIB_DCA 118462306a36Sopenharmony_ci 118562306a36Sopenharmony_cistatic int qib_notify_dca(struct notifier_block *, unsigned long, void *); 118662306a36Sopenharmony_cistatic struct notifier_block dca_notifier = { 118762306a36Sopenharmony_ci .notifier_call = qib_notify_dca, 118862306a36Sopenharmony_ci .next = NULL, 118962306a36Sopenharmony_ci .priority = 0 119062306a36Sopenharmony_ci}; 119162306a36Sopenharmony_ci 119262306a36Sopenharmony_cistatic int qib_notify_dca_device(struct device *device, void *data) 119362306a36Sopenharmony_ci{ 119462306a36Sopenharmony_ci struct qib_devdata *dd = dev_get_drvdata(device); 119562306a36Sopenharmony_ci unsigned long event = *(unsigned long *)data; 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_ci return dd->f_notify_dca(dd, event); 119862306a36Sopenharmony_ci} 119962306a36Sopenharmony_ci 120062306a36Sopenharmony_cistatic int qib_notify_dca(struct notifier_block *nb, unsigned long event, 120162306a36Sopenharmony_ci void *p) 120262306a36Sopenharmony_ci{ 120362306a36Sopenharmony_ci int rval; 120462306a36Sopenharmony_ci 120562306a36Sopenharmony_ci rval = driver_for_each_device(&qib_driver.driver, NULL, 120662306a36Sopenharmony_ci &event, qib_notify_dca_device); 120762306a36Sopenharmony_ci return rval ? NOTIFY_BAD : NOTIFY_DONE; 120862306a36Sopenharmony_ci} 120962306a36Sopenharmony_ci 121062306a36Sopenharmony_ci#endif 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci/* 121362306a36Sopenharmony_ci * Do all the generic driver unit- and chip-independent memory 121462306a36Sopenharmony_ci * allocation and initialization. 121562306a36Sopenharmony_ci */ 121662306a36Sopenharmony_cistatic int __init qib_ib_init(void) 121762306a36Sopenharmony_ci{ 121862306a36Sopenharmony_ci int ret; 121962306a36Sopenharmony_ci 122062306a36Sopenharmony_ci ret = qib_dev_init(); 122162306a36Sopenharmony_ci if (ret) 122262306a36Sopenharmony_ci goto bail; 122362306a36Sopenharmony_ci 122462306a36Sopenharmony_ci /* 122562306a36Sopenharmony_ci * These must be called before the driver is registered with 122662306a36Sopenharmony_ci * the PCI subsystem. 122762306a36Sopenharmony_ci */ 122862306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_QIB_DCA 122962306a36Sopenharmony_ci dca_register_notify(&dca_notifier); 123062306a36Sopenharmony_ci#endif 123162306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 123262306a36Sopenharmony_ci qib_dbg_init(); 123362306a36Sopenharmony_ci#endif 123462306a36Sopenharmony_ci ret = pci_register_driver(&qib_driver); 123562306a36Sopenharmony_ci if (ret < 0) { 123662306a36Sopenharmony_ci pr_err("Unable to register driver: error %d\n", -ret); 123762306a36Sopenharmony_ci goto bail_dev; 123862306a36Sopenharmony_ci } 123962306a36Sopenharmony_ci 124062306a36Sopenharmony_ci /* not fatal if it doesn't work */ 124162306a36Sopenharmony_ci if (qib_init_qibfs()) 124262306a36Sopenharmony_ci pr_err("Unable to register ipathfs\n"); 124362306a36Sopenharmony_ci goto bail; /* all OK */ 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_cibail_dev: 124662306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_QIB_DCA 124762306a36Sopenharmony_ci dca_unregister_notify(&dca_notifier); 124862306a36Sopenharmony_ci#endif 124962306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 125062306a36Sopenharmony_ci qib_dbg_exit(); 125162306a36Sopenharmony_ci#endif 125262306a36Sopenharmony_ci qib_dev_cleanup(); 125362306a36Sopenharmony_cibail: 125462306a36Sopenharmony_ci return ret; 125562306a36Sopenharmony_ci} 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_cimodule_init(qib_ib_init); 125862306a36Sopenharmony_ci 125962306a36Sopenharmony_ci/* 126062306a36Sopenharmony_ci * Do the non-unit driver cleanup, memory free, etc. at unload. 126162306a36Sopenharmony_ci */ 126262306a36Sopenharmony_cistatic void __exit qib_ib_cleanup(void) 126362306a36Sopenharmony_ci{ 126462306a36Sopenharmony_ci int ret; 126562306a36Sopenharmony_ci 126662306a36Sopenharmony_ci ret = qib_exit_qibfs(); 126762306a36Sopenharmony_ci if (ret) 126862306a36Sopenharmony_ci pr_err( 126962306a36Sopenharmony_ci "Unable to cleanup counter filesystem: error %d\n", 127062306a36Sopenharmony_ci -ret); 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_ci#ifdef CONFIG_INFINIBAND_QIB_DCA 127362306a36Sopenharmony_ci dca_unregister_notify(&dca_notifier); 127462306a36Sopenharmony_ci#endif 127562306a36Sopenharmony_ci pci_unregister_driver(&qib_driver); 127662306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 127762306a36Sopenharmony_ci qib_dbg_exit(); 127862306a36Sopenharmony_ci#endif 127962306a36Sopenharmony_ci 128062306a36Sopenharmony_ci qib_cpulist_count = 0; 128162306a36Sopenharmony_ci bitmap_free(qib_cpulist); 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_ci WARN_ON(!xa_empty(&qib_dev_table)); 128462306a36Sopenharmony_ci qib_dev_cleanup(); 128562306a36Sopenharmony_ci} 128662306a36Sopenharmony_ci 128762306a36Sopenharmony_cimodule_exit(qib_ib_cleanup); 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci/* this can only be called after a successful initialization */ 129062306a36Sopenharmony_cistatic void cleanup_device_data(struct qib_devdata *dd) 129162306a36Sopenharmony_ci{ 129262306a36Sopenharmony_ci int ctxt; 129362306a36Sopenharmony_ci int pidx; 129462306a36Sopenharmony_ci struct qib_ctxtdata **tmp; 129562306a36Sopenharmony_ci unsigned long flags; 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_ci /* users can't do anything more with chip */ 129862306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) { 129962306a36Sopenharmony_ci if (dd->pport[pidx].statusp) 130062306a36Sopenharmony_ci *dd->pport[pidx].statusp &= ~QIB_STATUS_CHIP_PRESENT; 130162306a36Sopenharmony_ci 130262306a36Sopenharmony_ci spin_lock(&dd->pport[pidx].cc_shadow_lock); 130362306a36Sopenharmony_ci 130462306a36Sopenharmony_ci kfree(dd->pport[pidx].congestion_entries); 130562306a36Sopenharmony_ci dd->pport[pidx].congestion_entries = NULL; 130662306a36Sopenharmony_ci kfree(dd->pport[pidx].ccti_entries); 130762306a36Sopenharmony_ci dd->pport[pidx].ccti_entries = NULL; 130862306a36Sopenharmony_ci kfree(dd->pport[pidx].ccti_entries_shadow); 130962306a36Sopenharmony_ci dd->pport[pidx].ccti_entries_shadow = NULL; 131062306a36Sopenharmony_ci kfree(dd->pport[pidx].congestion_entries_shadow); 131162306a36Sopenharmony_ci dd->pport[pidx].congestion_entries_shadow = NULL; 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_ci spin_unlock(&dd->pport[pidx].cc_shadow_lock); 131462306a36Sopenharmony_ci } 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_ci qib_disable_wc(dd); 131762306a36Sopenharmony_ci 131862306a36Sopenharmony_ci if (dd->pioavailregs_dma) { 131962306a36Sopenharmony_ci dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE, 132062306a36Sopenharmony_ci (void *) dd->pioavailregs_dma, 132162306a36Sopenharmony_ci dd->pioavailregs_phys); 132262306a36Sopenharmony_ci dd->pioavailregs_dma = NULL; 132362306a36Sopenharmony_ci } 132462306a36Sopenharmony_ci 132562306a36Sopenharmony_ci if (dd->pageshadow) { 132662306a36Sopenharmony_ci struct page **tmpp = dd->pageshadow; 132762306a36Sopenharmony_ci dma_addr_t *tmpd = dd->physshadow; 132862306a36Sopenharmony_ci int i; 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci for (ctxt = 0; ctxt < dd->cfgctxts; ctxt++) { 133162306a36Sopenharmony_ci int ctxt_tidbase = ctxt * dd->rcvtidcnt; 133262306a36Sopenharmony_ci int maxtid = ctxt_tidbase + dd->rcvtidcnt; 133362306a36Sopenharmony_ci 133462306a36Sopenharmony_ci for (i = ctxt_tidbase; i < maxtid; i++) { 133562306a36Sopenharmony_ci if (!tmpp[i]) 133662306a36Sopenharmony_ci continue; 133762306a36Sopenharmony_ci dma_unmap_page(&dd->pcidev->dev, tmpd[i], 133862306a36Sopenharmony_ci PAGE_SIZE, DMA_FROM_DEVICE); 133962306a36Sopenharmony_ci qib_release_user_pages(&tmpp[i], 1); 134062306a36Sopenharmony_ci tmpp[i] = NULL; 134162306a36Sopenharmony_ci } 134262306a36Sopenharmony_ci } 134362306a36Sopenharmony_ci 134462306a36Sopenharmony_ci dd->pageshadow = NULL; 134562306a36Sopenharmony_ci vfree(tmpp); 134662306a36Sopenharmony_ci dd->physshadow = NULL; 134762306a36Sopenharmony_ci vfree(tmpd); 134862306a36Sopenharmony_ci } 134962306a36Sopenharmony_ci 135062306a36Sopenharmony_ci /* 135162306a36Sopenharmony_ci * Free any resources still in use (usually just kernel contexts) 135262306a36Sopenharmony_ci * at unload; we do for ctxtcnt, because that's what we allocate. 135362306a36Sopenharmony_ci * We acquire lock to be really paranoid that rcd isn't being 135462306a36Sopenharmony_ci * accessed from some interrupt-related code (that should not happen, 135562306a36Sopenharmony_ci * but best to be sure). 135662306a36Sopenharmony_ci */ 135762306a36Sopenharmony_ci spin_lock_irqsave(&dd->uctxt_lock, flags); 135862306a36Sopenharmony_ci tmp = dd->rcd; 135962306a36Sopenharmony_ci dd->rcd = NULL; 136062306a36Sopenharmony_ci spin_unlock_irqrestore(&dd->uctxt_lock, flags); 136162306a36Sopenharmony_ci for (ctxt = 0; tmp && ctxt < dd->ctxtcnt; ctxt++) { 136262306a36Sopenharmony_ci struct qib_ctxtdata *rcd = tmp[ctxt]; 136362306a36Sopenharmony_ci 136462306a36Sopenharmony_ci tmp[ctxt] = NULL; /* debugging paranoia */ 136562306a36Sopenharmony_ci qib_free_ctxtdata(dd, rcd); 136662306a36Sopenharmony_ci } 136762306a36Sopenharmony_ci kfree(tmp); 136862306a36Sopenharmony_ci} 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci/* 137162306a36Sopenharmony_ci * Clean up on unit shutdown, or error during unit load after 137262306a36Sopenharmony_ci * successful initialization. 137362306a36Sopenharmony_ci */ 137462306a36Sopenharmony_cistatic void qib_postinit_cleanup(struct qib_devdata *dd) 137562306a36Sopenharmony_ci{ 137662306a36Sopenharmony_ci /* 137762306a36Sopenharmony_ci * Clean up chip-specific stuff. 137862306a36Sopenharmony_ci * We check for NULL here, because it's outside 137962306a36Sopenharmony_ci * the kregbase check, and we need to call it 138062306a36Sopenharmony_ci * after the free_irq. Thus it's possible that 138162306a36Sopenharmony_ci * the function pointers were never initialized. 138262306a36Sopenharmony_ci */ 138362306a36Sopenharmony_ci if (dd->f_cleanup) 138462306a36Sopenharmony_ci dd->f_cleanup(dd); 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_ci qib_pcie_ddcleanup(dd); 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci cleanup_device_data(dd); 138962306a36Sopenharmony_ci 139062306a36Sopenharmony_ci qib_free_devdata(dd); 139162306a36Sopenharmony_ci} 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_cistatic int qib_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 139462306a36Sopenharmony_ci{ 139562306a36Sopenharmony_ci int ret, j, pidx, initfail; 139662306a36Sopenharmony_ci struct qib_devdata *dd = NULL; 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_ci ret = qib_pcie_init(pdev, ent); 139962306a36Sopenharmony_ci if (ret) 140062306a36Sopenharmony_ci goto bail; 140162306a36Sopenharmony_ci 140262306a36Sopenharmony_ci /* 140362306a36Sopenharmony_ci * Do device-specific initialiation, function table setup, dd 140462306a36Sopenharmony_ci * allocation, etc. 140562306a36Sopenharmony_ci */ 140662306a36Sopenharmony_ci switch (ent->device) { 140762306a36Sopenharmony_ci case PCI_DEVICE_ID_QLOGIC_IB_6120: 140862306a36Sopenharmony_ci#ifdef CONFIG_PCI_MSI 140962306a36Sopenharmony_ci dd = qib_init_iba6120_funcs(pdev, ent); 141062306a36Sopenharmony_ci#else 141162306a36Sopenharmony_ci qib_early_err(&pdev->dev, 141262306a36Sopenharmony_ci "Intel PCIE device 0x%x cannot work if CONFIG_PCI_MSI is not enabled\n", 141362306a36Sopenharmony_ci ent->device); 141462306a36Sopenharmony_ci dd = ERR_PTR(-ENODEV); 141562306a36Sopenharmony_ci#endif 141662306a36Sopenharmony_ci break; 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ci case PCI_DEVICE_ID_QLOGIC_IB_7220: 141962306a36Sopenharmony_ci dd = qib_init_iba7220_funcs(pdev, ent); 142062306a36Sopenharmony_ci break; 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_ci case PCI_DEVICE_ID_QLOGIC_IB_7322: 142362306a36Sopenharmony_ci dd = qib_init_iba7322_funcs(pdev, ent); 142462306a36Sopenharmony_ci break; 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ci default: 142762306a36Sopenharmony_ci qib_early_err(&pdev->dev, 142862306a36Sopenharmony_ci "Failing on unknown Intel deviceid 0x%x\n", 142962306a36Sopenharmony_ci ent->device); 143062306a36Sopenharmony_ci ret = -ENODEV; 143162306a36Sopenharmony_ci } 143262306a36Sopenharmony_ci 143362306a36Sopenharmony_ci if (IS_ERR(dd)) 143462306a36Sopenharmony_ci ret = PTR_ERR(dd); 143562306a36Sopenharmony_ci if (ret) 143662306a36Sopenharmony_ci goto bail; /* error already printed */ 143762306a36Sopenharmony_ci 143862306a36Sopenharmony_ci ret = qib_create_workqueues(dd); 143962306a36Sopenharmony_ci if (ret) 144062306a36Sopenharmony_ci goto bail; 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_ci /* do the generic initialization */ 144362306a36Sopenharmony_ci initfail = qib_init(dd, 0); 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_ci ret = qib_register_ib_device(dd); 144662306a36Sopenharmony_ci 144762306a36Sopenharmony_ci /* 144862306a36Sopenharmony_ci * Now ready for use. this should be cleared whenever we 144962306a36Sopenharmony_ci * detect a reset, or initiate one. If earlier failure, 145062306a36Sopenharmony_ci * we still create devices, so diags, etc. can be used 145162306a36Sopenharmony_ci * to determine cause of problem. 145262306a36Sopenharmony_ci */ 145362306a36Sopenharmony_ci if (!qib_mini_init && !initfail && !ret) 145462306a36Sopenharmony_ci dd->flags |= QIB_INITTED; 145562306a36Sopenharmony_ci 145662306a36Sopenharmony_ci j = qib_device_create(dd); 145762306a36Sopenharmony_ci if (j) 145862306a36Sopenharmony_ci qib_dev_err(dd, "Failed to create /dev devices: %d\n", -j); 145962306a36Sopenharmony_ci j = qibfs_add(dd); 146062306a36Sopenharmony_ci if (j) 146162306a36Sopenharmony_ci qib_dev_err(dd, "Failed filesystem setup for counters: %d\n", 146262306a36Sopenharmony_ci -j); 146362306a36Sopenharmony_ci 146462306a36Sopenharmony_ci if (qib_mini_init || initfail || ret) { 146562306a36Sopenharmony_ci qib_stop_timers(dd); 146662306a36Sopenharmony_ci flush_workqueue(ib_wq); 146762306a36Sopenharmony_ci for (pidx = 0; pidx < dd->num_pports; ++pidx) 146862306a36Sopenharmony_ci dd->f_quiet_serdes(dd->pport + pidx); 146962306a36Sopenharmony_ci if (qib_mini_init) 147062306a36Sopenharmony_ci goto bail; 147162306a36Sopenharmony_ci if (!j) { 147262306a36Sopenharmony_ci (void) qibfs_remove(dd); 147362306a36Sopenharmony_ci qib_device_remove(dd); 147462306a36Sopenharmony_ci } 147562306a36Sopenharmony_ci if (!ret) 147662306a36Sopenharmony_ci qib_unregister_ib_device(dd); 147762306a36Sopenharmony_ci qib_postinit_cleanup(dd); 147862306a36Sopenharmony_ci if (initfail) 147962306a36Sopenharmony_ci ret = initfail; 148062306a36Sopenharmony_ci goto bail; 148162306a36Sopenharmony_ci } 148262306a36Sopenharmony_ci 148362306a36Sopenharmony_ci ret = qib_enable_wc(dd); 148462306a36Sopenharmony_ci if (ret) { 148562306a36Sopenharmony_ci qib_dev_err(dd, 148662306a36Sopenharmony_ci "Write combining not enabled (err %d): performance may be poor\n", 148762306a36Sopenharmony_ci -ret); 148862306a36Sopenharmony_ci ret = 0; 148962306a36Sopenharmony_ci } 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_ci qib_verify_pioperf(dd); 149262306a36Sopenharmony_cibail: 149362306a36Sopenharmony_ci return ret; 149462306a36Sopenharmony_ci} 149562306a36Sopenharmony_ci 149662306a36Sopenharmony_cistatic void qib_remove_one(struct pci_dev *pdev) 149762306a36Sopenharmony_ci{ 149862306a36Sopenharmony_ci struct qib_devdata *dd = pci_get_drvdata(pdev); 149962306a36Sopenharmony_ci int ret; 150062306a36Sopenharmony_ci 150162306a36Sopenharmony_ci /* unregister from IB core */ 150262306a36Sopenharmony_ci qib_unregister_ib_device(dd); 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_ci /* 150562306a36Sopenharmony_ci * Disable the IB link, disable interrupts on the device, 150662306a36Sopenharmony_ci * clear dma engines, etc. 150762306a36Sopenharmony_ci */ 150862306a36Sopenharmony_ci if (!qib_mini_init) 150962306a36Sopenharmony_ci qib_shutdown_device(dd); 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_ci qib_stop_timers(dd); 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci /* wait until all of our (qsfp) queue_work() calls complete */ 151462306a36Sopenharmony_ci flush_workqueue(ib_wq); 151562306a36Sopenharmony_ci 151662306a36Sopenharmony_ci ret = qibfs_remove(dd); 151762306a36Sopenharmony_ci if (ret) 151862306a36Sopenharmony_ci qib_dev_err(dd, "Failed counters filesystem cleanup: %d\n", 151962306a36Sopenharmony_ci -ret); 152062306a36Sopenharmony_ci 152162306a36Sopenharmony_ci qib_device_remove(dd); 152262306a36Sopenharmony_ci 152362306a36Sopenharmony_ci qib_postinit_cleanup(dd); 152462306a36Sopenharmony_ci} 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_cistatic void qib_shutdown_one(struct pci_dev *pdev) 152762306a36Sopenharmony_ci{ 152862306a36Sopenharmony_ci struct qib_devdata *dd = pci_get_drvdata(pdev); 152962306a36Sopenharmony_ci 153062306a36Sopenharmony_ci qib_shutdown_device(dd); 153162306a36Sopenharmony_ci} 153262306a36Sopenharmony_ci 153362306a36Sopenharmony_ci/** 153462306a36Sopenharmony_ci * qib_create_rcvhdrq - create a receive header queue 153562306a36Sopenharmony_ci * @dd: the qlogic_ib device 153662306a36Sopenharmony_ci * @rcd: the context data 153762306a36Sopenharmony_ci * 153862306a36Sopenharmony_ci * This must be contiguous memory (from an i/o perspective), and must be 153962306a36Sopenharmony_ci * DMA'able (which means for some systems, it will go through an IOMMU, 154062306a36Sopenharmony_ci * or be forced into a low address range). 154162306a36Sopenharmony_ci */ 154262306a36Sopenharmony_ciint qib_create_rcvhdrq(struct qib_devdata *dd, struct qib_ctxtdata *rcd) 154362306a36Sopenharmony_ci{ 154462306a36Sopenharmony_ci unsigned amt; 154562306a36Sopenharmony_ci int old_node_id; 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_ci if (!rcd->rcvhdrq) { 154862306a36Sopenharmony_ci dma_addr_t phys_hdrqtail; 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ci amt = ALIGN(dd->rcvhdrcnt * dd->rcvhdrentsize * 155162306a36Sopenharmony_ci sizeof(u32), PAGE_SIZE); 155262306a36Sopenharmony_ci 155362306a36Sopenharmony_ci old_node_id = dev_to_node(&dd->pcidev->dev); 155462306a36Sopenharmony_ci set_dev_node(&dd->pcidev->dev, rcd->node_id); 155562306a36Sopenharmony_ci rcd->rcvhdrq = dma_alloc_coherent(&dd->pcidev->dev, amt, 155662306a36Sopenharmony_ci &rcd->rcvhdrq_phys, GFP_KERNEL); 155762306a36Sopenharmony_ci set_dev_node(&dd->pcidev->dev, old_node_id); 155862306a36Sopenharmony_ci 155962306a36Sopenharmony_ci if (!rcd->rcvhdrq) { 156062306a36Sopenharmony_ci qib_dev_err(dd, 156162306a36Sopenharmony_ci "attempt to allocate %d bytes for ctxt %u rcvhdrq failed\n", 156262306a36Sopenharmony_ci amt, rcd->ctxt); 156362306a36Sopenharmony_ci goto bail; 156462306a36Sopenharmony_ci } 156562306a36Sopenharmony_ci 156662306a36Sopenharmony_ci if (rcd->ctxt >= dd->first_user_ctxt) { 156762306a36Sopenharmony_ci rcd->user_event_mask = vmalloc_user(PAGE_SIZE); 156862306a36Sopenharmony_ci if (!rcd->user_event_mask) 156962306a36Sopenharmony_ci goto bail_free_hdrq; 157062306a36Sopenharmony_ci } 157162306a36Sopenharmony_ci 157262306a36Sopenharmony_ci if (!(dd->flags & QIB_NODMA_RTAIL)) { 157362306a36Sopenharmony_ci set_dev_node(&dd->pcidev->dev, rcd->node_id); 157462306a36Sopenharmony_ci rcd->rcvhdrtail_kvaddr = dma_alloc_coherent( 157562306a36Sopenharmony_ci &dd->pcidev->dev, PAGE_SIZE, &phys_hdrqtail, 157662306a36Sopenharmony_ci GFP_KERNEL); 157762306a36Sopenharmony_ci set_dev_node(&dd->pcidev->dev, old_node_id); 157862306a36Sopenharmony_ci if (!rcd->rcvhdrtail_kvaddr) 157962306a36Sopenharmony_ci goto bail_free; 158062306a36Sopenharmony_ci rcd->rcvhdrqtailaddr_phys = phys_hdrqtail; 158162306a36Sopenharmony_ci } 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_ci rcd->rcvhdrq_size = amt; 158462306a36Sopenharmony_ci } 158562306a36Sopenharmony_ci 158662306a36Sopenharmony_ci /* clear for security and sanity on each use */ 158762306a36Sopenharmony_ci memset(rcd->rcvhdrq, 0, rcd->rcvhdrq_size); 158862306a36Sopenharmony_ci if (rcd->rcvhdrtail_kvaddr) 158962306a36Sopenharmony_ci memset(rcd->rcvhdrtail_kvaddr, 0, PAGE_SIZE); 159062306a36Sopenharmony_ci return 0; 159162306a36Sopenharmony_ci 159262306a36Sopenharmony_cibail_free: 159362306a36Sopenharmony_ci qib_dev_err(dd, 159462306a36Sopenharmony_ci "attempt to allocate 1 page for ctxt %u rcvhdrqtailaddr failed\n", 159562306a36Sopenharmony_ci rcd->ctxt); 159662306a36Sopenharmony_ci vfree(rcd->user_event_mask); 159762306a36Sopenharmony_ci rcd->user_event_mask = NULL; 159862306a36Sopenharmony_cibail_free_hdrq: 159962306a36Sopenharmony_ci dma_free_coherent(&dd->pcidev->dev, amt, rcd->rcvhdrq, 160062306a36Sopenharmony_ci rcd->rcvhdrq_phys); 160162306a36Sopenharmony_ci rcd->rcvhdrq = NULL; 160262306a36Sopenharmony_cibail: 160362306a36Sopenharmony_ci return -ENOMEM; 160462306a36Sopenharmony_ci} 160562306a36Sopenharmony_ci 160662306a36Sopenharmony_ci/** 160762306a36Sopenharmony_ci * qib_setup_eagerbufs - allocate eager buffers, both kernel and user contexts. 160862306a36Sopenharmony_ci * @rcd: the context we are setting up. 160962306a36Sopenharmony_ci * 161062306a36Sopenharmony_ci * Allocate the eager TID buffers and program them into hip. 161162306a36Sopenharmony_ci * They are no longer completely contiguous, we do multiple allocation 161262306a36Sopenharmony_ci * calls. Otherwise we get the OOM code involved, by asking for too 161362306a36Sopenharmony_ci * much per call, with disastrous results on some kernels. 161462306a36Sopenharmony_ci */ 161562306a36Sopenharmony_ciint qib_setup_eagerbufs(struct qib_ctxtdata *rcd) 161662306a36Sopenharmony_ci{ 161762306a36Sopenharmony_ci struct qib_devdata *dd = rcd->dd; 161862306a36Sopenharmony_ci unsigned e, egrcnt, egrperchunk, chunk, egrsize, egroff; 161962306a36Sopenharmony_ci size_t size; 162062306a36Sopenharmony_ci int old_node_id; 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci egrcnt = rcd->rcvegrcnt; 162362306a36Sopenharmony_ci egroff = rcd->rcvegr_tid_base; 162462306a36Sopenharmony_ci egrsize = dd->rcvegrbufsize; 162562306a36Sopenharmony_ci 162662306a36Sopenharmony_ci chunk = rcd->rcvegrbuf_chunks; 162762306a36Sopenharmony_ci egrperchunk = rcd->rcvegrbufs_perchunk; 162862306a36Sopenharmony_ci size = rcd->rcvegrbuf_size; 162962306a36Sopenharmony_ci if (!rcd->rcvegrbuf) { 163062306a36Sopenharmony_ci rcd->rcvegrbuf = 163162306a36Sopenharmony_ci kcalloc_node(chunk, sizeof(rcd->rcvegrbuf[0]), 163262306a36Sopenharmony_ci GFP_KERNEL, rcd->node_id); 163362306a36Sopenharmony_ci if (!rcd->rcvegrbuf) 163462306a36Sopenharmony_ci goto bail; 163562306a36Sopenharmony_ci } 163662306a36Sopenharmony_ci if (!rcd->rcvegrbuf_phys) { 163762306a36Sopenharmony_ci rcd->rcvegrbuf_phys = 163862306a36Sopenharmony_ci kmalloc_array_node(chunk, 163962306a36Sopenharmony_ci sizeof(rcd->rcvegrbuf_phys[0]), 164062306a36Sopenharmony_ci GFP_KERNEL, rcd->node_id); 164162306a36Sopenharmony_ci if (!rcd->rcvegrbuf_phys) 164262306a36Sopenharmony_ci goto bail_rcvegrbuf; 164362306a36Sopenharmony_ci } 164462306a36Sopenharmony_ci for (e = 0; e < rcd->rcvegrbuf_chunks; e++) { 164562306a36Sopenharmony_ci if (rcd->rcvegrbuf[e]) 164662306a36Sopenharmony_ci continue; 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci old_node_id = dev_to_node(&dd->pcidev->dev); 164962306a36Sopenharmony_ci set_dev_node(&dd->pcidev->dev, rcd->node_id); 165062306a36Sopenharmony_ci rcd->rcvegrbuf[e] = 165162306a36Sopenharmony_ci dma_alloc_coherent(&dd->pcidev->dev, size, 165262306a36Sopenharmony_ci &rcd->rcvegrbuf_phys[e], 165362306a36Sopenharmony_ci GFP_KERNEL); 165462306a36Sopenharmony_ci set_dev_node(&dd->pcidev->dev, old_node_id); 165562306a36Sopenharmony_ci if (!rcd->rcvegrbuf[e]) 165662306a36Sopenharmony_ci goto bail_rcvegrbuf_phys; 165762306a36Sopenharmony_ci } 165862306a36Sopenharmony_ci 165962306a36Sopenharmony_ci rcd->rcvegr_phys = rcd->rcvegrbuf_phys[0]; 166062306a36Sopenharmony_ci 166162306a36Sopenharmony_ci for (e = chunk = 0; chunk < rcd->rcvegrbuf_chunks; chunk++) { 166262306a36Sopenharmony_ci dma_addr_t pa = rcd->rcvegrbuf_phys[chunk]; 166362306a36Sopenharmony_ci unsigned i; 166462306a36Sopenharmony_ci 166562306a36Sopenharmony_ci /* clear for security and sanity on each use */ 166662306a36Sopenharmony_ci memset(rcd->rcvegrbuf[chunk], 0, size); 166762306a36Sopenharmony_ci 166862306a36Sopenharmony_ci for (i = 0; e < egrcnt && i < egrperchunk; e++, i++) { 166962306a36Sopenharmony_ci dd->f_put_tid(dd, e + egroff + 167062306a36Sopenharmony_ci (u64 __iomem *) 167162306a36Sopenharmony_ci ((char __iomem *) 167262306a36Sopenharmony_ci dd->kregbase + 167362306a36Sopenharmony_ci dd->rcvegrbase), 167462306a36Sopenharmony_ci RCVHQ_RCV_TYPE_EAGER, pa); 167562306a36Sopenharmony_ci pa += egrsize; 167662306a36Sopenharmony_ci } 167762306a36Sopenharmony_ci cond_resched(); /* don't hog the cpu */ 167862306a36Sopenharmony_ci } 167962306a36Sopenharmony_ci 168062306a36Sopenharmony_ci return 0; 168162306a36Sopenharmony_ci 168262306a36Sopenharmony_cibail_rcvegrbuf_phys: 168362306a36Sopenharmony_ci for (e = 0; e < rcd->rcvegrbuf_chunks && rcd->rcvegrbuf[e]; e++) 168462306a36Sopenharmony_ci dma_free_coherent(&dd->pcidev->dev, size, 168562306a36Sopenharmony_ci rcd->rcvegrbuf[e], rcd->rcvegrbuf_phys[e]); 168662306a36Sopenharmony_ci kfree(rcd->rcvegrbuf_phys); 168762306a36Sopenharmony_ci rcd->rcvegrbuf_phys = NULL; 168862306a36Sopenharmony_cibail_rcvegrbuf: 168962306a36Sopenharmony_ci kfree(rcd->rcvegrbuf); 169062306a36Sopenharmony_ci rcd->rcvegrbuf = NULL; 169162306a36Sopenharmony_cibail: 169262306a36Sopenharmony_ci return -ENOMEM; 169362306a36Sopenharmony_ci} 169462306a36Sopenharmony_ci 169562306a36Sopenharmony_ci/* 169662306a36Sopenharmony_ci * Note: Changes to this routine should be mirrored 169762306a36Sopenharmony_ci * for the diagnostics routine qib_remap_ioaddr32(). 169862306a36Sopenharmony_ci * There is also related code for VL15 buffers in qib_init_7322_variables(). 169962306a36Sopenharmony_ci * The teardown code that unmaps is in qib_pcie_ddcleanup() 170062306a36Sopenharmony_ci */ 170162306a36Sopenharmony_ciint init_chip_wc_pat(struct qib_devdata *dd, u32 vl15buflen) 170262306a36Sopenharmony_ci{ 170362306a36Sopenharmony_ci u64 __iomem *qib_kregbase = NULL; 170462306a36Sopenharmony_ci void __iomem *qib_piobase = NULL; 170562306a36Sopenharmony_ci u64 __iomem *qib_userbase = NULL; 170662306a36Sopenharmony_ci u64 qib_kreglen; 170762306a36Sopenharmony_ci u64 qib_pio2koffset = dd->piobufbase & 0xffffffff; 170862306a36Sopenharmony_ci u64 qib_pio4koffset = dd->piobufbase >> 32; 170962306a36Sopenharmony_ci u64 qib_pio2klen = dd->piobcnt2k * dd->palign; 171062306a36Sopenharmony_ci u64 qib_pio4klen = dd->piobcnt4k * dd->align4k; 171162306a36Sopenharmony_ci u64 qib_physaddr = dd->physaddr; 171262306a36Sopenharmony_ci u64 qib_piolen; 171362306a36Sopenharmony_ci u64 qib_userlen = 0; 171462306a36Sopenharmony_ci 171562306a36Sopenharmony_ci /* 171662306a36Sopenharmony_ci * Free the old mapping because the kernel will try to reuse the 171762306a36Sopenharmony_ci * old mapping and not create a new mapping with the 171862306a36Sopenharmony_ci * write combining attribute. 171962306a36Sopenharmony_ci */ 172062306a36Sopenharmony_ci iounmap(dd->kregbase); 172162306a36Sopenharmony_ci dd->kregbase = NULL; 172262306a36Sopenharmony_ci 172362306a36Sopenharmony_ci /* 172462306a36Sopenharmony_ci * Assumes chip address space looks like: 172562306a36Sopenharmony_ci * - kregs + sregs + cregs + uregs (in any order) 172662306a36Sopenharmony_ci * - piobufs (2K and 4K bufs in either order) 172762306a36Sopenharmony_ci * or: 172862306a36Sopenharmony_ci * - kregs + sregs + cregs (in any order) 172962306a36Sopenharmony_ci * - piobufs (2K and 4K bufs in either order) 173062306a36Sopenharmony_ci * - uregs 173162306a36Sopenharmony_ci */ 173262306a36Sopenharmony_ci if (dd->piobcnt4k == 0) { 173362306a36Sopenharmony_ci qib_kreglen = qib_pio2koffset; 173462306a36Sopenharmony_ci qib_piolen = qib_pio2klen; 173562306a36Sopenharmony_ci } else if (qib_pio2koffset < qib_pio4koffset) { 173662306a36Sopenharmony_ci qib_kreglen = qib_pio2koffset; 173762306a36Sopenharmony_ci qib_piolen = qib_pio4koffset + qib_pio4klen - qib_kreglen; 173862306a36Sopenharmony_ci } else { 173962306a36Sopenharmony_ci qib_kreglen = qib_pio4koffset; 174062306a36Sopenharmony_ci qib_piolen = qib_pio2koffset + qib_pio2klen - qib_kreglen; 174162306a36Sopenharmony_ci } 174262306a36Sopenharmony_ci qib_piolen += vl15buflen; 174362306a36Sopenharmony_ci /* Map just the configured ports (not all hw ports) */ 174462306a36Sopenharmony_ci if (dd->uregbase > qib_kreglen) 174562306a36Sopenharmony_ci qib_userlen = dd->ureg_align * dd->cfgctxts; 174662306a36Sopenharmony_ci 174762306a36Sopenharmony_ci /* Sanity checks passed, now create the new mappings */ 174862306a36Sopenharmony_ci qib_kregbase = ioremap(qib_physaddr, qib_kreglen); 174962306a36Sopenharmony_ci if (!qib_kregbase) 175062306a36Sopenharmony_ci goto bail; 175162306a36Sopenharmony_ci 175262306a36Sopenharmony_ci qib_piobase = ioremap_wc(qib_physaddr + qib_kreglen, qib_piolen); 175362306a36Sopenharmony_ci if (!qib_piobase) 175462306a36Sopenharmony_ci goto bail_kregbase; 175562306a36Sopenharmony_ci 175662306a36Sopenharmony_ci if (qib_userlen) { 175762306a36Sopenharmony_ci qib_userbase = ioremap(qib_physaddr + dd->uregbase, 175862306a36Sopenharmony_ci qib_userlen); 175962306a36Sopenharmony_ci if (!qib_userbase) 176062306a36Sopenharmony_ci goto bail_piobase; 176162306a36Sopenharmony_ci } 176262306a36Sopenharmony_ci 176362306a36Sopenharmony_ci dd->kregbase = qib_kregbase; 176462306a36Sopenharmony_ci dd->kregend = (u64 __iomem *) 176562306a36Sopenharmony_ci ((char __iomem *) qib_kregbase + qib_kreglen); 176662306a36Sopenharmony_ci dd->piobase = qib_piobase; 176762306a36Sopenharmony_ci dd->pio2kbase = (void __iomem *) 176862306a36Sopenharmony_ci (((char __iomem *) dd->piobase) + 176962306a36Sopenharmony_ci qib_pio2koffset - qib_kreglen); 177062306a36Sopenharmony_ci if (dd->piobcnt4k) 177162306a36Sopenharmony_ci dd->pio4kbase = (void __iomem *) 177262306a36Sopenharmony_ci (((char __iomem *) dd->piobase) + 177362306a36Sopenharmony_ci qib_pio4koffset - qib_kreglen); 177462306a36Sopenharmony_ci if (qib_userlen) 177562306a36Sopenharmony_ci /* ureg will now be accessed relative to dd->userbase */ 177662306a36Sopenharmony_ci dd->userbase = qib_userbase; 177762306a36Sopenharmony_ci return 0; 177862306a36Sopenharmony_ci 177962306a36Sopenharmony_cibail_piobase: 178062306a36Sopenharmony_ci iounmap(qib_piobase); 178162306a36Sopenharmony_cibail_kregbase: 178262306a36Sopenharmony_ci iounmap(qib_kregbase); 178362306a36Sopenharmony_cibail: 178462306a36Sopenharmony_ci return -ENOMEM; 178562306a36Sopenharmony_ci} 1786