18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright (c) 2012, 2013 Intel Corporation.  All rights reserved.
38c2ecf20Sopenharmony_ci * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
48c2ecf20Sopenharmony_ci * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two
78c2ecf20Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
88c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
98c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the
108c2ecf20Sopenharmony_ci * OpenIB.org BSD license below:
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
138c2ecf20Sopenharmony_ci *     without modification, are permitted provided that the following
148c2ecf20Sopenharmony_ci *     conditions are met:
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci *      - Redistributions of source code must retain the above
178c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
188c2ecf20Sopenharmony_ci *        disclaimer.
198c2ecf20Sopenharmony_ci *
208c2ecf20Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
218c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
228c2ecf20Sopenharmony_ci *        disclaimer in the documentation and/or other materials
238c2ecf20Sopenharmony_ci *        provided with the distribution.
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
268c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
278c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
288c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
298c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
308c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
318c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
328c2ecf20Sopenharmony_ci * SOFTWARE.
338c2ecf20Sopenharmony_ci */
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#include <linux/pci.h>
368c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
378c2ecf20Sopenharmony_ci#include <linux/vmalloc.h>
388c2ecf20Sopenharmony_ci#include <linux/delay.h>
398c2ecf20Sopenharmony_ci#include <linux/module.h>
408c2ecf20Sopenharmony_ci#include <linux/printk.h>
418c2ecf20Sopenharmony_ci#ifdef CONFIG_INFINIBAND_QIB_DCA
428c2ecf20Sopenharmony_ci#include <linux/dca.h>
438c2ecf20Sopenharmony_ci#endif
448c2ecf20Sopenharmony_ci#include <rdma/rdma_vt.h>
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#include "qib.h"
478c2ecf20Sopenharmony_ci#include "qib_common.h"
488c2ecf20Sopenharmony_ci#include "qib_mad.h"
498c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
508c2ecf20Sopenharmony_ci#include "qib_debugfs.h"
518c2ecf20Sopenharmony_ci#include "qib_verbs.h"
528c2ecf20Sopenharmony_ci#endif
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci#undef pr_fmt
558c2ecf20Sopenharmony_ci#define pr_fmt(fmt) QIB_DRV_NAME ": " fmt
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci/*
588c2ecf20Sopenharmony_ci * min buffers we want to have per context, after driver
598c2ecf20Sopenharmony_ci */
608c2ecf20Sopenharmony_ci#define QIB_MIN_USER_CTXT_BUFCNT 7
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci#define QLOGIC_IB_R_SOFTWARE_MASK 0xFF
638c2ecf20Sopenharmony_ci#define QLOGIC_IB_R_SOFTWARE_SHIFT 24
648c2ecf20Sopenharmony_ci#define QLOGIC_IB_R_EMULATOR_MASK (1ULL<<62)
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci/*
678c2ecf20Sopenharmony_ci * Number of ctxts we are configured to use (to allow for more pio
688c2ecf20Sopenharmony_ci * buffers per ctxt, etc.)  Zero means use chip value.
698c2ecf20Sopenharmony_ci */
708c2ecf20Sopenharmony_ciushort qib_cfgctxts;
718c2ecf20Sopenharmony_cimodule_param_named(cfgctxts, qib_cfgctxts, ushort, S_IRUGO);
728c2ecf20Sopenharmony_ciMODULE_PARM_DESC(cfgctxts, "Set max number of contexts to use");
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ciunsigned qib_numa_aware;
758c2ecf20Sopenharmony_cimodule_param_named(numa_aware, qib_numa_aware, uint, S_IRUGO);
768c2ecf20Sopenharmony_ciMODULE_PARM_DESC(numa_aware,
778c2ecf20Sopenharmony_ci	"0 -> PSM allocation close to HCA, 1 -> PSM allocation local to process");
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci/*
808c2ecf20Sopenharmony_ci * If set, do not write to any regs if avoidable, hack to allow
818c2ecf20Sopenharmony_ci * check for deranged default register values.
828c2ecf20Sopenharmony_ci */
838c2ecf20Sopenharmony_ciushort qib_mini_init;
848c2ecf20Sopenharmony_cimodule_param_named(mini_init, qib_mini_init, ushort, S_IRUGO);
858c2ecf20Sopenharmony_ciMODULE_PARM_DESC(mini_init, "If set, do minimal diag init");
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ciunsigned qib_n_krcv_queues;
888c2ecf20Sopenharmony_cimodule_param_named(krcvqs, qib_n_krcv_queues, uint, S_IRUGO);
898c2ecf20Sopenharmony_ciMODULE_PARM_DESC(krcvqs, "number of kernel receive queues per IB port");
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ciunsigned qib_cc_table_size;
928c2ecf20Sopenharmony_cimodule_param_named(cc_table_size, qib_cc_table_size, uint, S_IRUGO);
938c2ecf20Sopenharmony_ciMODULE_PARM_DESC(cc_table_size, "Congestion control table entries 0 (CCA disabled - default), min = 128, max = 1984");
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_cistatic void verify_interrupt(struct timer_list *);
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ciDEFINE_XARRAY_FLAGS(qib_dev_table, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
988c2ecf20Sopenharmony_ciu32 qib_cpulist_count;
998c2ecf20Sopenharmony_ciunsigned long *qib_cpulist;
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci/* set number of contexts we'll actually use */
1028c2ecf20Sopenharmony_civoid qib_set_ctxtcnt(struct qib_devdata *dd)
1038c2ecf20Sopenharmony_ci{
1048c2ecf20Sopenharmony_ci	if (!qib_cfgctxts) {
1058c2ecf20Sopenharmony_ci		dd->cfgctxts = dd->first_user_ctxt + num_online_cpus();
1068c2ecf20Sopenharmony_ci		if (dd->cfgctxts > dd->ctxtcnt)
1078c2ecf20Sopenharmony_ci			dd->cfgctxts = dd->ctxtcnt;
1088c2ecf20Sopenharmony_ci	} else if (qib_cfgctxts < dd->num_pports)
1098c2ecf20Sopenharmony_ci		dd->cfgctxts = dd->ctxtcnt;
1108c2ecf20Sopenharmony_ci	else if (qib_cfgctxts <= dd->ctxtcnt)
1118c2ecf20Sopenharmony_ci		dd->cfgctxts = qib_cfgctxts;
1128c2ecf20Sopenharmony_ci	else
1138c2ecf20Sopenharmony_ci		dd->cfgctxts = dd->ctxtcnt;
1148c2ecf20Sopenharmony_ci	dd->freectxts = (dd->first_user_ctxt > dd->cfgctxts) ? 0 :
1158c2ecf20Sopenharmony_ci		dd->cfgctxts - dd->first_user_ctxt;
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci/*
1198c2ecf20Sopenharmony_ci * Common code for creating the receive context array.
1208c2ecf20Sopenharmony_ci */
1218c2ecf20Sopenharmony_ciint qib_create_ctxts(struct qib_devdata *dd)
1228c2ecf20Sopenharmony_ci{
1238c2ecf20Sopenharmony_ci	unsigned i;
1248c2ecf20Sopenharmony_ci	int local_node_id = pcibus_to_node(dd->pcidev->bus);
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	if (local_node_id < 0)
1278c2ecf20Sopenharmony_ci		local_node_id = numa_node_id();
1288c2ecf20Sopenharmony_ci	dd->assigned_node_id = local_node_id;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	/*
1318c2ecf20Sopenharmony_ci	 * Allocate full ctxtcnt array, rather than just cfgctxts, because
1328c2ecf20Sopenharmony_ci	 * cleanup iterates across all possible ctxts.
1338c2ecf20Sopenharmony_ci	 */
1348c2ecf20Sopenharmony_ci	dd->rcd = kcalloc(dd->ctxtcnt, sizeof(*dd->rcd), GFP_KERNEL);
1358c2ecf20Sopenharmony_ci	if (!dd->rcd)
1368c2ecf20Sopenharmony_ci		return -ENOMEM;
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	/* create (one or more) kctxt */
1398c2ecf20Sopenharmony_ci	for (i = 0; i < dd->first_user_ctxt; ++i) {
1408c2ecf20Sopenharmony_ci		struct qib_pportdata *ppd;
1418c2ecf20Sopenharmony_ci		struct qib_ctxtdata *rcd;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci		if (dd->skip_kctxt_mask & (1 << i))
1448c2ecf20Sopenharmony_ci			continue;
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci		ppd = dd->pport + (i % dd->num_pports);
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci		rcd = qib_create_ctxtdata(ppd, i, dd->assigned_node_id);
1498c2ecf20Sopenharmony_ci		if (!rcd) {
1508c2ecf20Sopenharmony_ci			qib_dev_err(dd,
1518c2ecf20Sopenharmony_ci				"Unable to allocate ctxtdata for Kernel ctxt, failing\n");
1528c2ecf20Sopenharmony_ci			kfree(dd->rcd);
1538c2ecf20Sopenharmony_ci			dd->rcd = NULL;
1548c2ecf20Sopenharmony_ci			return -ENOMEM;
1558c2ecf20Sopenharmony_ci		}
1568c2ecf20Sopenharmony_ci		rcd->pkeys[0] = QIB_DEFAULT_P_KEY;
1578c2ecf20Sopenharmony_ci		rcd->seq_cnt = 1;
1588c2ecf20Sopenharmony_ci	}
1598c2ecf20Sopenharmony_ci	return 0;
1608c2ecf20Sopenharmony_ci}
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci/*
1638c2ecf20Sopenharmony_ci * Common code for user and kernel context setup.
1648c2ecf20Sopenharmony_ci */
1658c2ecf20Sopenharmony_cistruct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *ppd, u32 ctxt,
1668c2ecf20Sopenharmony_ci	int node_id)
1678c2ecf20Sopenharmony_ci{
1688c2ecf20Sopenharmony_ci	struct qib_devdata *dd = ppd->dd;
1698c2ecf20Sopenharmony_ci	struct qib_ctxtdata *rcd;
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci	rcd = kzalloc_node(sizeof(*rcd), GFP_KERNEL, node_id);
1728c2ecf20Sopenharmony_ci	if (rcd) {
1738c2ecf20Sopenharmony_ci		INIT_LIST_HEAD(&rcd->qp_wait_list);
1748c2ecf20Sopenharmony_ci		rcd->node_id = node_id;
1758c2ecf20Sopenharmony_ci		rcd->ppd = ppd;
1768c2ecf20Sopenharmony_ci		rcd->dd = dd;
1778c2ecf20Sopenharmony_ci		rcd->cnt = 1;
1788c2ecf20Sopenharmony_ci		rcd->ctxt = ctxt;
1798c2ecf20Sopenharmony_ci		dd->rcd[ctxt] = rcd;
1808c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
1818c2ecf20Sopenharmony_ci		if (ctxt < dd->first_user_ctxt) { /* N/A for PSM contexts */
1828c2ecf20Sopenharmony_ci			rcd->opstats = kzalloc_node(sizeof(*rcd->opstats),
1838c2ecf20Sopenharmony_ci				GFP_KERNEL, node_id);
1848c2ecf20Sopenharmony_ci			if (!rcd->opstats) {
1858c2ecf20Sopenharmony_ci				kfree(rcd);
1868c2ecf20Sopenharmony_ci				qib_dev_err(dd,
1878c2ecf20Sopenharmony_ci					"Unable to allocate per ctxt stats buffer\n");
1888c2ecf20Sopenharmony_ci				return NULL;
1898c2ecf20Sopenharmony_ci			}
1908c2ecf20Sopenharmony_ci		}
1918c2ecf20Sopenharmony_ci#endif
1928c2ecf20Sopenharmony_ci		dd->f_init_ctxt(rcd);
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci		/*
1958c2ecf20Sopenharmony_ci		 * To avoid wasting a lot of memory, we allocate 32KB chunks
1968c2ecf20Sopenharmony_ci		 * of physically contiguous memory, advance through it until
1978c2ecf20Sopenharmony_ci		 * used up and then allocate more.  Of course, we need
1988c2ecf20Sopenharmony_ci		 * memory to store those extra pointers, now.  32KB seems to
1998c2ecf20Sopenharmony_ci		 * be the most that is "safe" under memory pressure
2008c2ecf20Sopenharmony_ci		 * (creating large files and then copying them over
2018c2ecf20Sopenharmony_ci		 * NFS while doing lots of MPI jobs).  The OOM killer can
2028c2ecf20Sopenharmony_ci		 * get invoked, even though we say we can sleep and this can
2038c2ecf20Sopenharmony_ci		 * cause significant system problems....
2048c2ecf20Sopenharmony_ci		 */
2058c2ecf20Sopenharmony_ci		rcd->rcvegrbuf_size = 0x8000;
2068c2ecf20Sopenharmony_ci		rcd->rcvegrbufs_perchunk =
2078c2ecf20Sopenharmony_ci			rcd->rcvegrbuf_size / dd->rcvegrbufsize;
2088c2ecf20Sopenharmony_ci		rcd->rcvegrbuf_chunks = (rcd->rcvegrcnt +
2098c2ecf20Sopenharmony_ci			rcd->rcvegrbufs_perchunk - 1) /
2108c2ecf20Sopenharmony_ci			rcd->rcvegrbufs_perchunk;
2118c2ecf20Sopenharmony_ci		rcd->rcvegrbufs_perchunk_shift =
2128c2ecf20Sopenharmony_ci			ilog2(rcd->rcvegrbufs_perchunk);
2138c2ecf20Sopenharmony_ci	}
2148c2ecf20Sopenharmony_ci	return rcd;
2158c2ecf20Sopenharmony_ci}
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci/*
2188c2ecf20Sopenharmony_ci * Common code for initializing the physical port structure.
2198c2ecf20Sopenharmony_ci */
2208c2ecf20Sopenharmony_ciint qib_init_pportdata(struct qib_pportdata *ppd, struct qib_devdata *dd,
2218c2ecf20Sopenharmony_ci			u8 hw_pidx, u8 port)
2228c2ecf20Sopenharmony_ci{
2238c2ecf20Sopenharmony_ci	int size;
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	ppd->dd = dd;
2268c2ecf20Sopenharmony_ci	ppd->hw_pidx = hw_pidx;
2278c2ecf20Sopenharmony_ci	ppd->port = port; /* IB port number, not index */
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	spin_lock_init(&ppd->sdma_lock);
2308c2ecf20Sopenharmony_ci	spin_lock_init(&ppd->lflags_lock);
2318c2ecf20Sopenharmony_ci	spin_lock_init(&ppd->cc_shadow_lock);
2328c2ecf20Sopenharmony_ci	init_waitqueue_head(&ppd->state_wait);
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	timer_setup(&ppd->symerr_clear_timer, qib_clear_symerror_on_linkup, 0);
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci	ppd->qib_wq = NULL;
2378c2ecf20Sopenharmony_ci	ppd->ibport_data.pmastats =
2388c2ecf20Sopenharmony_ci		alloc_percpu(struct qib_pma_counters);
2398c2ecf20Sopenharmony_ci	if (!ppd->ibport_data.pmastats)
2408c2ecf20Sopenharmony_ci		return -ENOMEM;
2418c2ecf20Sopenharmony_ci	ppd->ibport_data.rvp.rc_acks = alloc_percpu(u64);
2428c2ecf20Sopenharmony_ci	ppd->ibport_data.rvp.rc_qacks = alloc_percpu(u64);
2438c2ecf20Sopenharmony_ci	ppd->ibport_data.rvp.rc_delayed_comp = alloc_percpu(u64);
2448c2ecf20Sopenharmony_ci	if (!(ppd->ibport_data.rvp.rc_acks) ||
2458c2ecf20Sopenharmony_ci	    !(ppd->ibport_data.rvp.rc_qacks) ||
2468c2ecf20Sopenharmony_ci	    !(ppd->ibport_data.rvp.rc_delayed_comp))
2478c2ecf20Sopenharmony_ci		return -ENOMEM;
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	if (qib_cc_table_size < IB_CCT_MIN_ENTRIES)
2508c2ecf20Sopenharmony_ci		goto bail;
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	ppd->cc_supported_table_entries = min(max_t(int, qib_cc_table_size,
2538c2ecf20Sopenharmony_ci		IB_CCT_MIN_ENTRIES), IB_CCT_ENTRIES*IB_CC_TABLE_CAP_DEFAULT);
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	ppd->cc_max_table_entries =
2568c2ecf20Sopenharmony_ci		ppd->cc_supported_table_entries/IB_CCT_ENTRIES;
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	size = IB_CC_TABLE_CAP_DEFAULT * sizeof(struct ib_cc_table_entry)
2598c2ecf20Sopenharmony_ci		* IB_CCT_ENTRIES;
2608c2ecf20Sopenharmony_ci	ppd->ccti_entries = kzalloc(size, GFP_KERNEL);
2618c2ecf20Sopenharmony_ci	if (!ppd->ccti_entries)
2628c2ecf20Sopenharmony_ci		goto bail;
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	size = IB_CC_CCS_ENTRIES * sizeof(struct ib_cc_congestion_entry);
2658c2ecf20Sopenharmony_ci	ppd->congestion_entries = kzalloc(size, GFP_KERNEL);
2668c2ecf20Sopenharmony_ci	if (!ppd->congestion_entries)
2678c2ecf20Sopenharmony_ci		goto bail_1;
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci	size = sizeof(struct cc_table_shadow);
2708c2ecf20Sopenharmony_ci	ppd->ccti_entries_shadow = kzalloc(size, GFP_KERNEL);
2718c2ecf20Sopenharmony_ci	if (!ppd->ccti_entries_shadow)
2728c2ecf20Sopenharmony_ci		goto bail_2;
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	size = sizeof(struct ib_cc_congestion_setting_attr);
2758c2ecf20Sopenharmony_ci	ppd->congestion_entries_shadow = kzalloc(size, GFP_KERNEL);
2768c2ecf20Sopenharmony_ci	if (!ppd->congestion_entries_shadow)
2778c2ecf20Sopenharmony_ci		goto bail_3;
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	return 0;
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_cibail_3:
2828c2ecf20Sopenharmony_ci	kfree(ppd->ccti_entries_shadow);
2838c2ecf20Sopenharmony_ci	ppd->ccti_entries_shadow = NULL;
2848c2ecf20Sopenharmony_cibail_2:
2858c2ecf20Sopenharmony_ci	kfree(ppd->congestion_entries);
2868c2ecf20Sopenharmony_ci	ppd->congestion_entries = NULL;
2878c2ecf20Sopenharmony_cibail_1:
2888c2ecf20Sopenharmony_ci	kfree(ppd->ccti_entries);
2898c2ecf20Sopenharmony_ci	ppd->ccti_entries = NULL;
2908c2ecf20Sopenharmony_cibail:
2918c2ecf20Sopenharmony_ci	/* User is intentionally disabling the congestion control agent */
2928c2ecf20Sopenharmony_ci	if (!qib_cc_table_size)
2938c2ecf20Sopenharmony_ci		return 0;
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	if (qib_cc_table_size < IB_CCT_MIN_ENTRIES) {
2968c2ecf20Sopenharmony_ci		qib_cc_table_size = 0;
2978c2ecf20Sopenharmony_ci		qib_dev_err(dd,
2988c2ecf20Sopenharmony_ci		 "Congestion Control table size %d less than minimum %d for port %d\n",
2998c2ecf20Sopenharmony_ci		 qib_cc_table_size, IB_CCT_MIN_ENTRIES, port);
3008c2ecf20Sopenharmony_ci	}
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ci	qib_dev_err(dd, "Congestion Control Agent disabled for port %d\n",
3038c2ecf20Sopenharmony_ci		port);
3048c2ecf20Sopenharmony_ci	return 0;
3058c2ecf20Sopenharmony_ci}
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_cistatic int init_pioavailregs(struct qib_devdata *dd)
3088c2ecf20Sopenharmony_ci{
3098c2ecf20Sopenharmony_ci	int ret, pidx;
3108c2ecf20Sopenharmony_ci	u64 *status_page;
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci	dd->pioavailregs_dma = dma_alloc_coherent(
3138c2ecf20Sopenharmony_ci		&dd->pcidev->dev, PAGE_SIZE, &dd->pioavailregs_phys,
3148c2ecf20Sopenharmony_ci		GFP_KERNEL);
3158c2ecf20Sopenharmony_ci	if (!dd->pioavailregs_dma) {
3168c2ecf20Sopenharmony_ci		qib_dev_err(dd,
3178c2ecf20Sopenharmony_ci			"failed to allocate PIOavail reg area in memory\n");
3188c2ecf20Sopenharmony_ci		ret = -ENOMEM;
3198c2ecf20Sopenharmony_ci		goto done;
3208c2ecf20Sopenharmony_ci	}
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	/*
3238c2ecf20Sopenharmony_ci	 * We really want L2 cache aligned, but for current CPUs of
3248c2ecf20Sopenharmony_ci	 * interest, they are the same.
3258c2ecf20Sopenharmony_ci	 */
3268c2ecf20Sopenharmony_ci	status_page = (u64 *)
3278c2ecf20Sopenharmony_ci		((char *) dd->pioavailregs_dma +
3288c2ecf20Sopenharmony_ci		 ((2 * L1_CACHE_BYTES +
3298c2ecf20Sopenharmony_ci		   dd->pioavregs * sizeof(u64)) & ~L1_CACHE_BYTES));
3308c2ecf20Sopenharmony_ci	/* device status comes first, for backwards compatibility */
3318c2ecf20Sopenharmony_ci	dd->devstatusp = status_page;
3328c2ecf20Sopenharmony_ci	*status_page++ = 0;
3338c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
3348c2ecf20Sopenharmony_ci		dd->pport[pidx].statusp = status_page;
3358c2ecf20Sopenharmony_ci		*status_page++ = 0;
3368c2ecf20Sopenharmony_ci	}
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	/*
3398c2ecf20Sopenharmony_ci	 * Setup buffer to hold freeze and other messages, accessible to
3408c2ecf20Sopenharmony_ci	 * apps, following statusp.  This is per-unit, not per port.
3418c2ecf20Sopenharmony_ci	 */
3428c2ecf20Sopenharmony_ci	dd->freezemsg = (char *) status_page;
3438c2ecf20Sopenharmony_ci	*dd->freezemsg = 0;
3448c2ecf20Sopenharmony_ci	/* length of msg buffer is "whatever is left" */
3458c2ecf20Sopenharmony_ci	ret = (char *) status_page - (char *) dd->pioavailregs_dma;
3468c2ecf20Sopenharmony_ci	dd->freezelen = PAGE_SIZE - ret;
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_ci	ret = 0;
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_cidone:
3518c2ecf20Sopenharmony_ci	return ret;
3528c2ecf20Sopenharmony_ci}
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci/**
3558c2ecf20Sopenharmony_ci * init_shadow_tids - allocate the shadow TID array
3568c2ecf20Sopenharmony_ci * @dd: the qlogic_ib device
3578c2ecf20Sopenharmony_ci *
3588c2ecf20Sopenharmony_ci * allocate the shadow TID array, so we can qib_munlock previous
3598c2ecf20Sopenharmony_ci * entries.  It may make more sense to move the pageshadow to the
3608c2ecf20Sopenharmony_ci * ctxt data structure, so we only allocate memory for ctxts actually
3618c2ecf20Sopenharmony_ci * in use, since we at 8k per ctxt, now.
3628c2ecf20Sopenharmony_ci * We don't want failures here to prevent use of the driver/chip,
3638c2ecf20Sopenharmony_ci * so no return value.
3648c2ecf20Sopenharmony_ci */
3658c2ecf20Sopenharmony_cistatic void init_shadow_tids(struct qib_devdata *dd)
3668c2ecf20Sopenharmony_ci{
3678c2ecf20Sopenharmony_ci	struct page **pages;
3688c2ecf20Sopenharmony_ci	dma_addr_t *addrs;
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci	pages = vzalloc(array_size(sizeof(struct page *),
3718c2ecf20Sopenharmony_ci				   dd->cfgctxts * dd->rcvtidcnt));
3728c2ecf20Sopenharmony_ci	if (!pages)
3738c2ecf20Sopenharmony_ci		goto bail;
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci	addrs = vzalloc(array_size(sizeof(dma_addr_t),
3768c2ecf20Sopenharmony_ci				   dd->cfgctxts * dd->rcvtidcnt));
3778c2ecf20Sopenharmony_ci	if (!addrs)
3788c2ecf20Sopenharmony_ci		goto bail_free;
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	dd->pageshadow = pages;
3818c2ecf20Sopenharmony_ci	dd->physshadow = addrs;
3828c2ecf20Sopenharmony_ci	return;
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_cibail_free:
3858c2ecf20Sopenharmony_ci	vfree(pages);
3868c2ecf20Sopenharmony_cibail:
3878c2ecf20Sopenharmony_ci	dd->pageshadow = NULL;
3888c2ecf20Sopenharmony_ci}
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci/*
3918c2ecf20Sopenharmony_ci * Do initialization for device that is only needed on
3928c2ecf20Sopenharmony_ci * first detect, not on resets.
3938c2ecf20Sopenharmony_ci */
3948c2ecf20Sopenharmony_cistatic int loadtime_init(struct qib_devdata *dd)
3958c2ecf20Sopenharmony_ci{
3968c2ecf20Sopenharmony_ci	int ret = 0;
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_ci	if (((dd->revision >> QLOGIC_IB_R_SOFTWARE_SHIFT) &
3998c2ecf20Sopenharmony_ci	     QLOGIC_IB_R_SOFTWARE_MASK) != QIB_CHIP_SWVERSION) {
4008c2ecf20Sopenharmony_ci		qib_dev_err(dd,
4018c2ecf20Sopenharmony_ci			"Driver only handles version %d, chip swversion is %d (%llx), failing\n",
4028c2ecf20Sopenharmony_ci			QIB_CHIP_SWVERSION,
4038c2ecf20Sopenharmony_ci			(int)(dd->revision >>
4048c2ecf20Sopenharmony_ci				QLOGIC_IB_R_SOFTWARE_SHIFT) &
4058c2ecf20Sopenharmony_ci				QLOGIC_IB_R_SOFTWARE_MASK,
4068c2ecf20Sopenharmony_ci			(unsigned long long) dd->revision);
4078c2ecf20Sopenharmony_ci		ret = -ENOSYS;
4088c2ecf20Sopenharmony_ci		goto done;
4098c2ecf20Sopenharmony_ci	}
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	if (dd->revision & QLOGIC_IB_R_EMULATOR_MASK)
4128c2ecf20Sopenharmony_ci		qib_devinfo(dd->pcidev, "%s", dd->boardversion);
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_ci	spin_lock_init(&dd->pioavail_lock);
4158c2ecf20Sopenharmony_ci	spin_lock_init(&dd->sendctrl_lock);
4168c2ecf20Sopenharmony_ci	spin_lock_init(&dd->uctxt_lock);
4178c2ecf20Sopenharmony_ci	spin_lock_init(&dd->qib_diag_trans_lock);
4188c2ecf20Sopenharmony_ci	spin_lock_init(&dd->eep_st_lock);
4198c2ecf20Sopenharmony_ci	mutex_init(&dd->eep_lock);
4208c2ecf20Sopenharmony_ci
4218c2ecf20Sopenharmony_ci	if (qib_mini_init)
4228c2ecf20Sopenharmony_ci		goto done;
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci	ret = init_pioavailregs(dd);
4258c2ecf20Sopenharmony_ci	init_shadow_tids(dd);
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	qib_get_eeprom_info(dd);
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_ci	/* setup time (don't start yet) to verify we got interrupt */
4308c2ecf20Sopenharmony_ci	timer_setup(&dd->intrchk_timer, verify_interrupt, 0);
4318c2ecf20Sopenharmony_cidone:
4328c2ecf20Sopenharmony_ci	return ret;
4338c2ecf20Sopenharmony_ci}
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_ci/**
4368c2ecf20Sopenharmony_ci * init_after_reset - re-initialize after a reset
4378c2ecf20Sopenharmony_ci * @dd: the qlogic_ib device
4388c2ecf20Sopenharmony_ci *
4398c2ecf20Sopenharmony_ci * sanity check at least some of the values after reset, and
4408c2ecf20Sopenharmony_ci * ensure no receive or transmit (explicitly, in case reset
4418c2ecf20Sopenharmony_ci * failed
4428c2ecf20Sopenharmony_ci */
4438c2ecf20Sopenharmony_cistatic int init_after_reset(struct qib_devdata *dd)
4448c2ecf20Sopenharmony_ci{
4458c2ecf20Sopenharmony_ci	int i;
4468c2ecf20Sopenharmony_ci
4478c2ecf20Sopenharmony_ci	/*
4488c2ecf20Sopenharmony_ci	 * Ensure chip does no sends or receives, tail updates, or
4498c2ecf20Sopenharmony_ci	 * pioavail updates while we re-initialize.  This is mostly
4508c2ecf20Sopenharmony_ci	 * for the driver data structures, not chip registers.
4518c2ecf20Sopenharmony_ci	 */
4528c2ecf20Sopenharmony_ci	for (i = 0; i < dd->num_pports; ++i) {
4538c2ecf20Sopenharmony_ci		/*
4548c2ecf20Sopenharmony_ci		 * ctxt == -1 means "all contexts". Only really safe for
4558c2ecf20Sopenharmony_ci		 * _dis_abling things, as here.
4568c2ecf20Sopenharmony_ci		 */
4578c2ecf20Sopenharmony_ci		dd->f_rcvctrl(dd->pport + i, QIB_RCVCTRL_CTXT_DIS |
4588c2ecf20Sopenharmony_ci				  QIB_RCVCTRL_INTRAVAIL_DIS |
4598c2ecf20Sopenharmony_ci				  QIB_RCVCTRL_TAILUPD_DIS, -1);
4608c2ecf20Sopenharmony_ci		/* Redundant across ports for some, but no big deal.  */
4618c2ecf20Sopenharmony_ci		dd->f_sendctrl(dd->pport + i, QIB_SENDCTRL_SEND_DIS |
4628c2ecf20Sopenharmony_ci			QIB_SENDCTRL_AVAIL_DIS);
4638c2ecf20Sopenharmony_ci	}
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci	return 0;
4668c2ecf20Sopenharmony_ci}
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_cistatic void enable_chip(struct qib_devdata *dd)
4698c2ecf20Sopenharmony_ci{
4708c2ecf20Sopenharmony_ci	u64 rcvmask;
4718c2ecf20Sopenharmony_ci	int i;
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci	/*
4748c2ecf20Sopenharmony_ci	 * Enable PIO send, and update of PIOavail regs to memory.
4758c2ecf20Sopenharmony_ci	 */
4768c2ecf20Sopenharmony_ci	for (i = 0; i < dd->num_pports; ++i)
4778c2ecf20Sopenharmony_ci		dd->f_sendctrl(dd->pport + i, QIB_SENDCTRL_SEND_ENB |
4788c2ecf20Sopenharmony_ci			QIB_SENDCTRL_AVAIL_ENB);
4798c2ecf20Sopenharmony_ci	/*
4808c2ecf20Sopenharmony_ci	 * Enable kernel ctxts' receive and receive interrupt.
4818c2ecf20Sopenharmony_ci	 * Other ctxts done as user opens and inits them.
4828c2ecf20Sopenharmony_ci	 */
4838c2ecf20Sopenharmony_ci	rcvmask = QIB_RCVCTRL_CTXT_ENB | QIB_RCVCTRL_INTRAVAIL_ENB;
4848c2ecf20Sopenharmony_ci	rcvmask |= (dd->flags & QIB_NODMA_RTAIL) ?
4858c2ecf20Sopenharmony_ci		  QIB_RCVCTRL_TAILUPD_DIS : QIB_RCVCTRL_TAILUPD_ENB;
4868c2ecf20Sopenharmony_ci	for (i = 0; dd->rcd && i < dd->first_user_ctxt; ++i) {
4878c2ecf20Sopenharmony_ci		struct qib_ctxtdata *rcd = dd->rcd[i];
4888c2ecf20Sopenharmony_ci
4898c2ecf20Sopenharmony_ci		if (rcd)
4908c2ecf20Sopenharmony_ci			dd->f_rcvctrl(rcd->ppd, rcvmask, i);
4918c2ecf20Sopenharmony_ci	}
4928c2ecf20Sopenharmony_ci}
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_cistatic void verify_interrupt(struct timer_list *t)
4958c2ecf20Sopenharmony_ci{
4968c2ecf20Sopenharmony_ci	struct qib_devdata *dd = from_timer(dd, t, intrchk_timer);
4978c2ecf20Sopenharmony_ci	u64 int_counter;
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci	if (!dd)
5008c2ecf20Sopenharmony_ci		return; /* being torn down */
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci	/*
5038c2ecf20Sopenharmony_ci	 * If we don't have a lid or any interrupts, let the user know and
5048c2ecf20Sopenharmony_ci	 * don't bother checking again.
5058c2ecf20Sopenharmony_ci	 */
5068c2ecf20Sopenharmony_ci	int_counter = qib_int_counter(dd) - dd->z_int_counter;
5078c2ecf20Sopenharmony_ci	if (int_counter == 0) {
5088c2ecf20Sopenharmony_ci		if (!dd->f_intr_fallback(dd))
5098c2ecf20Sopenharmony_ci			dev_err(&dd->pcidev->dev,
5108c2ecf20Sopenharmony_ci				"No interrupts detected, not usable.\n");
5118c2ecf20Sopenharmony_ci		else /* re-arm the timer to see if fallback works */
5128c2ecf20Sopenharmony_ci			mod_timer(&dd->intrchk_timer, jiffies + HZ/2);
5138c2ecf20Sopenharmony_ci	}
5148c2ecf20Sopenharmony_ci}
5158c2ecf20Sopenharmony_ci
5168c2ecf20Sopenharmony_cistatic void init_piobuf_state(struct qib_devdata *dd)
5178c2ecf20Sopenharmony_ci{
5188c2ecf20Sopenharmony_ci	int i, pidx;
5198c2ecf20Sopenharmony_ci	u32 uctxts;
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_ci	/*
5228c2ecf20Sopenharmony_ci	 * Ensure all buffers are free, and fifos empty.  Buffers
5238c2ecf20Sopenharmony_ci	 * are common, so only do once for port 0.
5248c2ecf20Sopenharmony_ci	 *
5258c2ecf20Sopenharmony_ci	 * After enable and qib_chg_pioavailkernel so we can safely
5268c2ecf20Sopenharmony_ci	 * enable pioavail updates and PIOENABLE.  After this, packets
5278c2ecf20Sopenharmony_ci	 * are ready and able to go out.
5288c2ecf20Sopenharmony_ci	 */
5298c2ecf20Sopenharmony_ci	dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_ALL);
5308c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx)
5318c2ecf20Sopenharmony_ci		dd->f_sendctrl(dd->pport + pidx, QIB_SENDCTRL_FLUSH);
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	/*
5348c2ecf20Sopenharmony_ci	 * If not all sendbufs are used, add the one to each of the lower
5358c2ecf20Sopenharmony_ci	 * numbered contexts.  pbufsctxt and lastctxt_piobuf are
5368c2ecf20Sopenharmony_ci	 * calculated in chip-specific code because it may cause some
5378c2ecf20Sopenharmony_ci	 * chip-specific adjustments to be made.
5388c2ecf20Sopenharmony_ci	 */
5398c2ecf20Sopenharmony_ci	uctxts = dd->cfgctxts - dd->first_user_ctxt;
5408c2ecf20Sopenharmony_ci	dd->ctxts_extrabuf = dd->pbufsctxt ?
5418c2ecf20Sopenharmony_ci		dd->lastctxt_piobuf - (dd->pbufsctxt * uctxts) : 0;
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_ci	/*
5448c2ecf20Sopenharmony_ci	 * Set up the shadow copies of the piobufavail registers,
5458c2ecf20Sopenharmony_ci	 * which we compare against the chip registers for now, and
5468c2ecf20Sopenharmony_ci	 * the in memory DMA'ed copies of the registers.
5478c2ecf20Sopenharmony_ci	 * By now pioavail updates to memory should have occurred, so
5488c2ecf20Sopenharmony_ci	 * copy them into our working/shadow registers; this is in
5498c2ecf20Sopenharmony_ci	 * case something went wrong with abort, but mostly to get the
5508c2ecf20Sopenharmony_ci	 * initial values of the generation bit correct.
5518c2ecf20Sopenharmony_ci	 */
5528c2ecf20Sopenharmony_ci	for (i = 0; i < dd->pioavregs; i++) {
5538c2ecf20Sopenharmony_ci		__le64 tmp;
5548c2ecf20Sopenharmony_ci
5558c2ecf20Sopenharmony_ci		tmp = dd->pioavailregs_dma[i];
5568c2ecf20Sopenharmony_ci		/*
5578c2ecf20Sopenharmony_ci		 * Don't need to worry about pioavailkernel here
5588c2ecf20Sopenharmony_ci		 * because we will call qib_chg_pioavailkernel() later
5598c2ecf20Sopenharmony_ci		 * in initialization, to busy out buffers as needed.
5608c2ecf20Sopenharmony_ci		 */
5618c2ecf20Sopenharmony_ci		dd->pioavailshadow[i] = le64_to_cpu(tmp);
5628c2ecf20Sopenharmony_ci	}
5638c2ecf20Sopenharmony_ci	while (i < ARRAY_SIZE(dd->pioavailshadow))
5648c2ecf20Sopenharmony_ci		dd->pioavailshadow[i++] = 0; /* for debugging sanity */
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci	/* after pioavailshadow is setup */
5678c2ecf20Sopenharmony_ci	qib_chg_pioavailkernel(dd, 0, dd->piobcnt2k + dd->piobcnt4k,
5688c2ecf20Sopenharmony_ci			       TXCHK_CHG_TYPE_KERN, NULL);
5698c2ecf20Sopenharmony_ci	dd->f_initvl15_bufs(dd);
5708c2ecf20Sopenharmony_ci}
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_ci/**
5738c2ecf20Sopenharmony_ci * qib_create_workqueues - create per port workqueues
5748c2ecf20Sopenharmony_ci * @dd: the qlogic_ib device
5758c2ecf20Sopenharmony_ci */
5768c2ecf20Sopenharmony_cistatic int qib_create_workqueues(struct qib_devdata *dd)
5778c2ecf20Sopenharmony_ci{
5788c2ecf20Sopenharmony_ci	int pidx;
5798c2ecf20Sopenharmony_ci	struct qib_pportdata *ppd;
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
5828c2ecf20Sopenharmony_ci		ppd = dd->pport + pidx;
5838c2ecf20Sopenharmony_ci		if (!ppd->qib_wq) {
5848c2ecf20Sopenharmony_ci			char wq_name[8]; /* 3 + 2 + 1 + 1 + 1 */
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_ci			snprintf(wq_name, sizeof(wq_name), "qib%d_%d",
5878c2ecf20Sopenharmony_ci				dd->unit, pidx);
5888c2ecf20Sopenharmony_ci			ppd->qib_wq = alloc_ordered_workqueue(wq_name,
5898c2ecf20Sopenharmony_ci							      WQ_MEM_RECLAIM);
5908c2ecf20Sopenharmony_ci			if (!ppd->qib_wq)
5918c2ecf20Sopenharmony_ci				goto wq_error;
5928c2ecf20Sopenharmony_ci		}
5938c2ecf20Sopenharmony_ci	}
5948c2ecf20Sopenharmony_ci	return 0;
5958c2ecf20Sopenharmony_ciwq_error:
5968c2ecf20Sopenharmony_ci	pr_err("create_singlethread_workqueue failed for port %d\n",
5978c2ecf20Sopenharmony_ci		pidx + 1);
5988c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
5998c2ecf20Sopenharmony_ci		ppd = dd->pport + pidx;
6008c2ecf20Sopenharmony_ci		if (ppd->qib_wq) {
6018c2ecf20Sopenharmony_ci			destroy_workqueue(ppd->qib_wq);
6028c2ecf20Sopenharmony_ci			ppd->qib_wq = NULL;
6038c2ecf20Sopenharmony_ci		}
6048c2ecf20Sopenharmony_ci	}
6058c2ecf20Sopenharmony_ci	return -ENOMEM;
6068c2ecf20Sopenharmony_ci}
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_cistatic void qib_free_pportdata(struct qib_pportdata *ppd)
6098c2ecf20Sopenharmony_ci{
6108c2ecf20Sopenharmony_ci	free_percpu(ppd->ibport_data.pmastats);
6118c2ecf20Sopenharmony_ci	free_percpu(ppd->ibport_data.rvp.rc_acks);
6128c2ecf20Sopenharmony_ci	free_percpu(ppd->ibport_data.rvp.rc_qacks);
6138c2ecf20Sopenharmony_ci	free_percpu(ppd->ibport_data.rvp.rc_delayed_comp);
6148c2ecf20Sopenharmony_ci	ppd->ibport_data.pmastats = NULL;
6158c2ecf20Sopenharmony_ci}
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_ci/**
6188c2ecf20Sopenharmony_ci * qib_init - do the actual initialization sequence on the chip
6198c2ecf20Sopenharmony_ci * @dd: the qlogic_ib device
6208c2ecf20Sopenharmony_ci * @reinit: reinitializing, so don't allocate new memory
6218c2ecf20Sopenharmony_ci *
6228c2ecf20Sopenharmony_ci * Do the actual initialization sequence on the chip.  This is done
6238c2ecf20Sopenharmony_ci * both from the init routine called from the PCI infrastructure, and
6248c2ecf20Sopenharmony_ci * when we reset the chip, or detect that it was reset internally,
6258c2ecf20Sopenharmony_ci * or it's administratively re-enabled.
6268c2ecf20Sopenharmony_ci *
6278c2ecf20Sopenharmony_ci * Memory allocation here and in called routines is only done in
6288c2ecf20Sopenharmony_ci * the first case (reinit == 0).  We have to be careful, because even
6298c2ecf20Sopenharmony_ci * without memory allocation, we need to re-write all the chip registers
6308c2ecf20Sopenharmony_ci * TIDs, etc. after the reset or enable has completed.
6318c2ecf20Sopenharmony_ci */
6328c2ecf20Sopenharmony_ciint qib_init(struct qib_devdata *dd, int reinit)
6338c2ecf20Sopenharmony_ci{
6348c2ecf20Sopenharmony_ci	int ret = 0, pidx, lastfail = 0;
6358c2ecf20Sopenharmony_ci	u32 portok = 0;
6368c2ecf20Sopenharmony_ci	unsigned i;
6378c2ecf20Sopenharmony_ci	struct qib_ctxtdata *rcd;
6388c2ecf20Sopenharmony_ci	struct qib_pportdata *ppd;
6398c2ecf20Sopenharmony_ci	unsigned long flags;
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci	/* Set linkstate to unknown, so we can watch for a transition. */
6428c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
6438c2ecf20Sopenharmony_ci		ppd = dd->pport + pidx;
6448c2ecf20Sopenharmony_ci		spin_lock_irqsave(&ppd->lflags_lock, flags);
6458c2ecf20Sopenharmony_ci		ppd->lflags &= ~(QIBL_LINKACTIVE | QIBL_LINKARMED |
6468c2ecf20Sopenharmony_ci				 QIBL_LINKDOWN | QIBL_LINKINIT |
6478c2ecf20Sopenharmony_ci				 QIBL_LINKV);
6488c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&ppd->lflags_lock, flags);
6498c2ecf20Sopenharmony_ci	}
6508c2ecf20Sopenharmony_ci
6518c2ecf20Sopenharmony_ci	if (reinit)
6528c2ecf20Sopenharmony_ci		ret = init_after_reset(dd);
6538c2ecf20Sopenharmony_ci	else
6548c2ecf20Sopenharmony_ci		ret = loadtime_init(dd);
6558c2ecf20Sopenharmony_ci	if (ret)
6568c2ecf20Sopenharmony_ci		goto done;
6578c2ecf20Sopenharmony_ci
6588c2ecf20Sopenharmony_ci	/* Bypass most chip-init, to get to device creation */
6598c2ecf20Sopenharmony_ci	if (qib_mini_init)
6608c2ecf20Sopenharmony_ci		return 0;
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci	ret = dd->f_late_initreg(dd);
6638c2ecf20Sopenharmony_ci	if (ret)
6648c2ecf20Sopenharmony_ci		goto done;
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ci	/* dd->rcd can be NULL if early init failed */
6678c2ecf20Sopenharmony_ci	for (i = 0; dd->rcd && i < dd->first_user_ctxt; ++i) {
6688c2ecf20Sopenharmony_ci		/*
6698c2ecf20Sopenharmony_ci		 * Set up the (kernel) rcvhdr queue and egr TIDs.  If doing
6708c2ecf20Sopenharmony_ci		 * re-init, the simplest way to handle this is to free
6718c2ecf20Sopenharmony_ci		 * existing, and re-allocate.
6728c2ecf20Sopenharmony_ci		 * Need to re-create rest of ctxt 0 ctxtdata as well.
6738c2ecf20Sopenharmony_ci		 */
6748c2ecf20Sopenharmony_ci		rcd = dd->rcd[i];
6758c2ecf20Sopenharmony_ci		if (!rcd)
6768c2ecf20Sopenharmony_ci			continue;
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci		lastfail = qib_create_rcvhdrq(dd, rcd);
6798c2ecf20Sopenharmony_ci		if (!lastfail)
6808c2ecf20Sopenharmony_ci			lastfail = qib_setup_eagerbufs(rcd);
6818c2ecf20Sopenharmony_ci		if (lastfail)
6828c2ecf20Sopenharmony_ci			qib_dev_err(dd,
6838c2ecf20Sopenharmony_ci				"failed to allocate kernel ctxt's rcvhdrq and/or egr bufs\n");
6848c2ecf20Sopenharmony_ci	}
6858c2ecf20Sopenharmony_ci
6868c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
6878c2ecf20Sopenharmony_ci		int mtu;
6888c2ecf20Sopenharmony_ci
6898c2ecf20Sopenharmony_ci		if (lastfail)
6908c2ecf20Sopenharmony_ci			ret = lastfail;
6918c2ecf20Sopenharmony_ci		ppd = dd->pport + pidx;
6928c2ecf20Sopenharmony_ci		mtu = ib_mtu_enum_to_int(qib_ibmtu);
6938c2ecf20Sopenharmony_ci		if (mtu == -1) {
6948c2ecf20Sopenharmony_ci			mtu = QIB_DEFAULT_MTU;
6958c2ecf20Sopenharmony_ci			qib_ibmtu = 0; /* don't leave invalid value */
6968c2ecf20Sopenharmony_ci		}
6978c2ecf20Sopenharmony_ci		/* set max we can ever have for this driver load */
6988c2ecf20Sopenharmony_ci		ppd->init_ibmaxlen = min(mtu > 2048 ?
6998c2ecf20Sopenharmony_ci					 dd->piosize4k : dd->piosize2k,
7008c2ecf20Sopenharmony_ci					 dd->rcvegrbufsize +
7018c2ecf20Sopenharmony_ci					 (dd->rcvhdrentsize << 2));
7028c2ecf20Sopenharmony_ci		/*
7038c2ecf20Sopenharmony_ci		 * Have to initialize ibmaxlen, but this will normally
7048c2ecf20Sopenharmony_ci		 * change immediately in qib_set_mtu().
7058c2ecf20Sopenharmony_ci		 */
7068c2ecf20Sopenharmony_ci		ppd->ibmaxlen = ppd->init_ibmaxlen;
7078c2ecf20Sopenharmony_ci		qib_set_mtu(ppd, mtu);
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci		spin_lock_irqsave(&ppd->lflags_lock, flags);
7108c2ecf20Sopenharmony_ci		ppd->lflags |= QIBL_IB_LINK_DISABLED;
7118c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&ppd->lflags_lock, flags);
7128c2ecf20Sopenharmony_ci
7138c2ecf20Sopenharmony_ci		lastfail = dd->f_bringup_serdes(ppd);
7148c2ecf20Sopenharmony_ci		if (lastfail) {
7158c2ecf20Sopenharmony_ci			qib_devinfo(dd->pcidev,
7168c2ecf20Sopenharmony_ci				 "Failed to bringup IB port %u\n", ppd->port);
7178c2ecf20Sopenharmony_ci			lastfail = -ENETDOWN;
7188c2ecf20Sopenharmony_ci			continue;
7198c2ecf20Sopenharmony_ci		}
7208c2ecf20Sopenharmony_ci
7218c2ecf20Sopenharmony_ci		portok++;
7228c2ecf20Sopenharmony_ci	}
7238c2ecf20Sopenharmony_ci
7248c2ecf20Sopenharmony_ci	if (!portok) {
7258c2ecf20Sopenharmony_ci		/* none of the ports initialized */
7268c2ecf20Sopenharmony_ci		if (!ret && lastfail)
7278c2ecf20Sopenharmony_ci			ret = lastfail;
7288c2ecf20Sopenharmony_ci		else if (!ret)
7298c2ecf20Sopenharmony_ci			ret = -ENETDOWN;
7308c2ecf20Sopenharmony_ci		/* but continue on, so we can debug cause */
7318c2ecf20Sopenharmony_ci	}
7328c2ecf20Sopenharmony_ci
7338c2ecf20Sopenharmony_ci	enable_chip(dd);
7348c2ecf20Sopenharmony_ci
7358c2ecf20Sopenharmony_ci	init_piobuf_state(dd);
7368c2ecf20Sopenharmony_ci
7378c2ecf20Sopenharmony_cidone:
7388c2ecf20Sopenharmony_ci	if (!ret) {
7398c2ecf20Sopenharmony_ci		/* chip is OK for user apps; mark it as initialized */
7408c2ecf20Sopenharmony_ci		for (pidx = 0; pidx < dd->num_pports; ++pidx) {
7418c2ecf20Sopenharmony_ci			ppd = dd->pport + pidx;
7428c2ecf20Sopenharmony_ci			/*
7438c2ecf20Sopenharmony_ci			 * Set status even if port serdes is not initialized
7448c2ecf20Sopenharmony_ci			 * so that diags will work.
7458c2ecf20Sopenharmony_ci			 */
7468c2ecf20Sopenharmony_ci			*ppd->statusp |= QIB_STATUS_CHIP_PRESENT |
7478c2ecf20Sopenharmony_ci				QIB_STATUS_INITTED;
7488c2ecf20Sopenharmony_ci			if (!ppd->link_speed_enabled)
7498c2ecf20Sopenharmony_ci				continue;
7508c2ecf20Sopenharmony_ci			if (dd->flags & QIB_HAS_SEND_DMA)
7518c2ecf20Sopenharmony_ci				ret = qib_setup_sdma(ppd);
7528c2ecf20Sopenharmony_ci			timer_setup(&ppd->hol_timer, qib_hol_event, 0);
7538c2ecf20Sopenharmony_ci			ppd->hol_state = QIB_HOL_UP;
7548c2ecf20Sopenharmony_ci		}
7558c2ecf20Sopenharmony_ci
7568c2ecf20Sopenharmony_ci		/* now we can enable all interrupts from the chip */
7578c2ecf20Sopenharmony_ci		dd->f_set_intr_state(dd, 1);
7588c2ecf20Sopenharmony_ci
7598c2ecf20Sopenharmony_ci		/*
7608c2ecf20Sopenharmony_ci		 * Setup to verify we get an interrupt, and fallback
7618c2ecf20Sopenharmony_ci		 * to an alternate if necessary and possible.
7628c2ecf20Sopenharmony_ci		 */
7638c2ecf20Sopenharmony_ci		mod_timer(&dd->intrchk_timer, jiffies + HZ/2);
7648c2ecf20Sopenharmony_ci		/* start stats retrieval timer */
7658c2ecf20Sopenharmony_ci		mod_timer(&dd->stats_timer, jiffies + HZ * ACTIVITY_TIMER);
7668c2ecf20Sopenharmony_ci	}
7678c2ecf20Sopenharmony_ci
7688c2ecf20Sopenharmony_ci	/* if ret is non-zero, we probably should do some cleanup here... */
7698c2ecf20Sopenharmony_ci	return ret;
7708c2ecf20Sopenharmony_ci}
7718c2ecf20Sopenharmony_ci
7728c2ecf20Sopenharmony_ci/*
7738c2ecf20Sopenharmony_ci * These next two routines are placeholders in case we don't have per-arch
7748c2ecf20Sopenharmony_ci * code for controlling write combining.  If explicit control of write
7758c2ecf20Sopenharmony_ci * combining is not available, performance will probably be awful.
7768c2ecf20Sopenharmony_ci */
7778c2ecf20Sopenharmony_ci
7788c2ecf20Sopenharmony_ciint __attribute__((weak)) qib_enable_wc(struct qib_devdata *dd)
7798c2ecf20Sopenharmony_ci{
7808c2ecf20Sopenharmony_ci	return -EOPNOTSUPP;
7818c2ecf20Sopenharmony_ci}
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_civoid __attribute__((weak)) qib_disable_wc(struct qib_devdata *dd)
7848c2ecf20Sopenharmony_ci{
7858c2ecf20Sopenharmony_ci}
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_cistruct qib_devdata *qib_lookup(int unit)
7888c2ecf20Sopenharmony_ci{
7898c2ecf20Sopenharmony_ci	return xa_load(&qib_dev_table, unit);
7908c2ecf20Sopenharmony_ci}
7918c2ecf20Sopenharmony_ci
7928c2ecf20Sopenharmony_ci/*
7938c2ecf20Sopenharmony_ci * Stop the timers during unit shutdown, or after an error late
7948c2ecf20Sopenharmony_ci * in initialization.
7958c2ecf20Sopenharmony_ci */
7968c2ecf20Sopenharmony_cistatic void qib_stop_timers(struct qib_devdata *dd)
7978c2ecf20Sopenharmony_ci{
7988c2ecf20Sopenharmony_ci	struct qib_pportdata *ppd;
7998c2ecf20Sopenharmony_ci	int pidx;
8008c2ecf20Sopenharmony_ci
8018c2ecf20Sopenharmony_ci	if (dd->stats_timer.function)
8028c2ecf20Sopenharmony_ci		del_timer_sync(&dd->stats_timer);
8038c2ecf20Sopenharmony_ci	if (dd->intrchk_timer.function)
8048c2ecf20Sopenharmony_ci		del_timer_sync(&dd->intrchk_timer);
8058c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
8068c2ecf20Sopenharmony_ci		ppd = dd->pport + pidx;
8078c2ecf20Sopenharmony_ci		if (ppd->hol_timer.function)
8088c2ecf20Sopenharmony_ci			del_timer_sync(&ppd->hol_timer);
8098c2ecf20Sopenharmony_ci		if (ppd->led_override_timer.function) {
8108c2ecf20Sopenharmony_ci			del_timer_sync(&ppd->led_override_timer);
8118c2ecf20Sopenharmony_ci			atomic_set(&ppd->led_override_timer_active, 0);
8128c2ecf20Sopenharmony_ci		}
8138c2ecf20Sopenharmony_ci		if (ppd->symerr_clear_timer.function)
8148c2ecf20Sopenharmony_ci			del_timer_sync(&ppd->symerr_clear_timer);
8158c2ecf20Sopenharmony_ci	}
8168c2ecf20Sopenharmony_ci}
8178c2ecf20Sopenharmony_ci
8188c2ecf20Sopenharmony_ci/**
8198c2ecf20Sopenharmony_ci * qib_shutdown_device - shut down a device
8208c2ecf20Sopenharmony_ci * @dd: the qlogic_ib device
8218c2ecf20Sopenharmony_ci *
8228c2ecf20Sopenharmony_ci * This is called to make the device quiet when we are about to
8238c2ecf20Sopenharmony_ci * unload the driver, and also when the device is administratively
8248c2ecf20Sopenharmony_ci * disabled.   It does not free any data structures.
8258c2ecf20Sopenharmony_ci * Everything it does has to be setup again by qib_init(dd, 1)
8268c2ecf20Sopenharmony_ci */
8278c2ecf20Sopenharmony_cistatic void qib_shutdown_device(struct qib_devdata *dd)
8288c2ecf20Sopenharmony_ci{
8298c2ecf20Sopenharmony_ci	struct qib_pportdata *ppd;
8308c2ecf20Sopenharmony_ci	unsigned pidx;
8318c2ecf20Sopenharmony_ci
8328c2ecf20Sopenharmony_ci	if (dd->flags & QIB_SHUTDOWN)
8338c2ecf20Sopenharmony_ci		return;
8348c2ecf20Sopenharmony_ci	dd->flags |= QIB_SHUTDOWN;
8358c2ecf20Sopenharmony_ci
8368c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
8378c2ecf20Sopenharmony_ci		ppd = dd->pport + pidx;
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_ci		spin_lock_irq(&ppd->lflags_lock);
8408c2ecf20Sopenharmony_ci		ppd->lflags &= ~(QIBL_LINKDOWN | QIBL_LINKINIT |
8418c2ecf20Sopenharmony_ci				 QIBL_LINKARMED | QIBL_LINKACTIVE |
8428c2ecf20Sopenharmony_ci				 QIBL_LINKV);
8438c2ecf20Sopenharmony_ci		spin_unlock_irq(&ppd->lflags_lock);
8448c2ecf20Sopenharmony_ci		*ppd->statusp &= ~(QIB_STATUS_IB_CONF | QIB_STATUS_IB_READY);
8458c2ecf20Sopenharmony_ci	}
8468c2ecf20Sopenharmony_ci	dd->flags &= ~QIB_INITTED;
8478c2ecf20Sopenharmony_ci
8488c2ecf20Sopenharmony_ci	/* mask interrupts, but not errors */
8498c2ecf20Sopenharmony_ci	dd->f_set_intr_state(dd, 0);
8508c2ecf20Sopenharmony_ci
8518c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
8528c2ecf20Sopenharmony_ci		ppd = dd->pport + pidx;
8538c2ecf20Sopenharmony_ci		dd->f_rcvctrl(ppd, QIB_RCVCTRL_TAILUPD_DIS |
8548c2ecf20Sopenharmony_ci				   QIB_RCVCTRL_CTXT_DIS |
8558c2ecf20Sopenharmony_ci				   QIB_RCVCTRL_INTRAVAIL_DIS |
8568c2ecf20Sopenharmony_ci				   QIB_RCVCTRL_PKEY_ENB, -1);
8578c2ecf20Sopenharmony_ci		/*
8588c2ecf20Sopenharmony_ci		 * Gracefully stop all sends allowing any in progress to
8598c2ecf20Sopenharmony_ci		 * trickle out first.
8608c2ecf20Sopenharmony_ci		 */
8618c2ecf20Sopenharmony_ci		dd->f_sendctrl(ppd, QIB_SENDCTRL_CLEAR);
8628c2ecf20Sopenharmony_ci	}
8638c2ecf20Sopenharmony_ci
8648c2ecf20Sopenharmony_ci	/*
8658c2ecf20Sopenharmony_ci	 * Enough for anything that's going to trickle out to have actually
8668c2ecf20Sopenharmony_ci	 * done so.
8678c2ecf20Sopenharmony_ci	 */
8688c2ecf20Sopenharmony_ci	udelay(20);
8698c2ecf20Sopenharmony_ci
8708c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
8718c2ecf20Sopenharmony_ci		ppd = dd->pport + pidx;
8728c2ecf20Sopenharmony_ci		dd->f_setextled(ppd, 0); /* make sure LEDs are off */
8738c2ecf20Sopenharmony_ci
8748c2ecf20Sopenharmony_ci		if (dd->flags & QIB_HAS_SEND_DMA)
8758c2ecf20Sopenharmony_ci			qib_teardown_sdma(ppd);
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_ci		dd->f_sendctrl(ppd, QIB_SENDCTRL_AVAIL_DIS |
8788c2ecf20Sopenharmony_ci				    QIB_SENDCTRL_SEND_DIS);
8798c2ecf20Sopenharmony_ci		/*
8808c2ecf20Sopenharmony_ci		 * Clear SerdesEnable.
8818c2ecf20Sopenharmony_ci		 * We can't count on interrupts since we are stopping.
8828c2ecf20Sopenharmony_ci		 */
8838c2ecf20Sopenharmony_ci		dd->f_quiet_serdes(ppd);
8848c2ecf20Sopenharmony_ci
8858c2ecf20Sopenharmony_ci		if (ppd->qib_wq) {
8868c2ecf20Sopenharmony_ci			destroy_workqueue(ppd->qib_wq);
8878c2ecf20Sopenharmony_ci			ppd->qib_wq = NULL;
8888c2ecf20Sopenharmony_ci		}
8898c2ecf20Sopenharmony_ci		qib_free_pportdata(ppd);
8908c2ecf20Sopenharmony_ci	}
8918c2ecf20Sopenharmony_ci
8928c2ecf20Sopenharmony_ci}
8938c2ecf20Sopenharmony_ci
8948c2ecf20Sopenharmony_ci/**
8958c2ecf20Sopenharmony_ci * qib_free_ctxtdata - free a context's allocated data
8968c2ecf20Sopenharmony_ci * @dd: the qlogic_ib device
8978c2ecf20Sopenharmony_ci * @rcd: the ctxtdata structure
8988c2ecf20Sopenharmony_ci *
8998c2ecf20Sopenharmony_ci * free up any allocated data for a context
9008c2ecf20Sopenharmony_ci * This should not touch anything that would affect a simultaneous
9018c2ecf20Sopenharmony_ci * re-allocation of context data, because it is called after qib_mutex
9028c2ecf20Sopenharmony_ci * is released (and can be called from reinit as well).
9038c2ecf20Sopenharmony_ci * It should never change any chip state, or global driver state.
9048c2ecf20Sopenharmony_ci */
9058c2ecf20Sopenharmony_civoid qib_free_ctxtdata(struct qib_devdata *dd, struct qib_ctxtdata *rcd)
9068c2ecf20Sopenharmony_ci{
9078c2ecf20Sopenharmony_ci	if (!rcd)
9088c2ecf20Sopenharmony_ci		return;
9098c2ecf20Sopenharmony_ci
9108c2ecf20Sopenharmony_ci	if (rcd->rcvhdrq) {
9118c2ecf20Sopenharmony_ci		dma_free_coherent(&dd->pcidev->dev, rcd->rcvhdrq_size,
9128c2ecf20Sopenharmony_ci				  rcd->rcvhdrq, rcd->rcvhdrq_phys);
9138c2ecf20Sopenharmony_ci		rcd->rcvhdrq = NULL;
9148c2ecf20Sopenharmony_ci		if (rcd->rcvhdrtail_kvaddr) {
9158c2ecf20Sopenharmony_ci			dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
9168c2ecf20Sopenharmony_ci					  rcd->rcvhdrtail_kvaddr,
9178c2ecf20Sopenharmony_ci					  rcd->rcvhdrqtailaddr_phys);
9188c2ecf20Sopenharmony_ci			rcd->rcvhdrtail_kvaddr = NULL;
9198c2ecf20Sopenharmony_ci		}
9208c2ecf20Sopenharmony_ci	}
9218c2ecf20Sopenharmony_ci	if (rcd->rcvegrbuf) {
9228c2ecf20Sopenharmony_ci		unsigned e;
9238c2ecf20Sopenharmony_ci
9248c2ecf20Sopenharmony_ci		for (e = 0; e < rcd->rcvegrbuf_chunks; e++) {
9258c2ecf20Sopenharmony_ci			void *base = rcd->rcvegrbuf[e];
9268c2ecf20Sopenharmony_ci			size_t size = rcd->rcvegrbuf_size;
9278c2ecf20Sopenharmony_ci
9288c2ecf20Sopenharmony_ci			dma_free_coherent(&dd->pcidev->dev, size,
9298c2ecf20Sopenharmony_ci					  base, rcd->rcvegrbuf_phys[e]);
9308c2ecf20Sopenharmony_ci		}
9318c2ecf20Sopenharmony_ci		kfree(rcd->rcvegrbuf);
9328c2ecf20Sopenharmony_ci		rcd->rcvegrbuf = NULL;
9338c2ecf20Sopenharmony_ci		kfree(rcd->rcvegrbuf_phys);
9348c2ecf20Sopenharmony_ci		rcd->rcvegrbuf_phys = NULL;
9358c2ecf20Sopenharmony_ci		rcd->rcvegrbuf_chunks = 0;
9368c2ecf20Sopenharmony_ci	}
9378c2ecf20Sopenharmony_ci
9388c2ecf20Sopenharmony_ci	kfree(rcd->tid_pg_list);
9398c2ecf20Sopenharmony_ci	vfree(rcd->user_event_mask);
9408c2ecf20Sopenharmony_ci	vfree(rcd->subctxt_uregbase);
9418c2ecf20Sopenharmony_ci	vfree(rcd->subctxt_rcvegrbuf);
9428c2ecf20Sopenharmony_ci	vfree(rcd->subctxt_rcvhdr_base);
9438c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
9448c2ecf20Sopenharmony_ci	kfree(rcd->opstats);
9458c2ecf20Sopenharmony_ci	rcd->opstats = NULL;
9468c2ecf20Sopenharmony_ci#endif
9478c2ecf20Sopenharmony_ci	kfree(rcd);
9488c2ecf20Sopenharmony_ci}
9498c2ecf20Sopenharmony_ci
9508c2ecf20Sopenharmony_ci/*
9518c2ecf20Sopenharmony_ci * Perform a PIO buffer bandwidth write test, to verify proper system
9528c2ecf20Sopenharmony_ci * configuration.  Even when all the setup calls work, occasionally
9538c2ecf20Sopenharmony_ci * BIOS or other issues can prevent write combining from working, or
9548c2ecf20Sopenharmony_ci * can cause other bandwidth problems to the chip.
9558c2ecf20Sopenharmony_ci *
9568c2ecf20Sopenharmony_ci * This test simply writes the same buffer over and over again, and
9578c2ecf20Sopenharmony_ci * measures close to the peak bandwidth to the chip (not testing
9588c2ecf20Sopenharmony_ci * data bandwidth to the wire).   On chips that use an address-based
9598c2ecf20Sopenharmony_ci * trigger to send packets to the wire, this is easy.  On chips that
9608c2ecf20Sopenharmony_ci * use a count to trigger, we want to make sure that the packet doesn't
9618c2ecf20Sopenharmony_ci * go out on the wire, or trigger flow control checks.
9628c2ecf20Sopenharmony_ci */
9638c2ecf20Sopenharmony_cistatic void qib_verify_pioperf(struct qib_devdata *dd)
9648c2ecf20Sopenharmony_ci{
9658c2ecf20Sopenharmony_ci	u32 pbnum, cnt, lcnt;
9668c2ecf20Sopenharmony_ci	u32 __iomem *piobuf;
9678c2ecf20Sopenharmony_ci	u32 *addr;
9688c2ecf20Sopenharmony_ci	u64 msecs, emsecs;
9698c2ecf20Sopenharmony_ci
9708c2ecf20Sopenharmony_ci	piobuf = dd->f_getsendbuf(dd->pport, 0ULL, &pbnum);
9718c2ecf20Sopenharmony_ci	if (!piobuf) {
9728c2ecf20Sopenharmony_ci		qib_devinfo(dd->pcidev,
9738c2ecf20Sopenharmony_ci			 "No PIObufs for checking perf, skipping\n");
9748c2ecf20Sopenharmony_ci		return;
9758c2ecf20Sopenharmony_ci	}
9768c2ecf20Sopenharmony_ci
9778c2ecf20Sopenharmony_ci	/*
9788c2ecf20Sopenharmony_ci	 * Enough to give us a reasonable test, less than piobuf size, and
9798c2ecf20Sopenharmony_ci	 * likely multiple of store buffer length.
9808c2ecf20Sopenharmony_ci	 */
9818c2ecf20Sopenharmony_ci	cnt = 1024;
9828c2ecf20Sopenharmony_ci
9838c2ecf20Sopenharmony_ci	addr = vmalloc(cnt);
9848c2ecf20Sopenharmony_ci	if (!addr)
9858c2ecf20Sopenharmony_ci		goto done;
9868c2ecf20Sopenharmony_ci
9878c2ecf20Sopenharmony_ci	preempt_disable();  /* we want reasonably accurate elapsed time */
9888c2ecf20Sopenharmony_ci	msecs = 1 + jiffies_to_msecs(jiffies);
9898c2ecf20Sopenharmony_ci	for (lcnt = 0; lcnt < 10000U; lcnt++) {
9908c2ecf20Sopenharmony_ci		/* wait until we cross msec boundary */
9918c2ecf20Sopenharmony_ci		if (jiffies_to_msecs(jiffies) >= msecs)
9928c2ecf20Sopenharmony_ci			break;
9938c2ecf20Sopenharmony_ci		udelay(1);
9948c2ecf20Sopenharmony_ci	}
9958c2ecf20Sopenharmony_ci
9968c2ecf20Sopenharmony_ci	dd->f_set_armlaunch(dd, 0);
9978c2ecf20Sopenharmony_ci
9988c2ecf20Sopenharmony_ci	/*
9998c2ecf20Sopenharmony_ci	 * length 0, no dwords actually sent
10008c2ecf20Sopenharmony_ci	 */
10018c2ecf20Sopenharmony_ci	writeq(0, piobuf);
10028c2ecf20Sopenharmony_ci	qib_flush_wc();
10038c2ecf20Sopenharmony_ci
10048c2ecf20Sopenharmony_ci	/*
10058c2ecf20Sopenharmony_ci	 * This is only roughly accurate, since even with preempt we
10068c2ecf20Sopenharmony_ci	 * still take interrupts that could take a while.   Running for
10078c2ecf20Sopenharmony_ci	 * >= 5 msec seems to get us "close enough" to accurate values.
10088c2ecf20Sopenharmony_ci	 */
10098c2ecf20Sopenharmony_ci	msecs = jiffies_to_msecs(jiffies);
10108c2ecf20Sopenharmony_ci	for (emsecs = lcnt = 0; emsecs <= 5UL; lcnt++) {
10118c2ecf20Sopenharmony_ci		qib_pio_copy(piobuf + 64, addr, cnt >> 2);
10128c2ecf20Sopenharmony_ci		emsecs = jiffies_to_msecs(jiffies) - msecs;
10138c2ecf20Sopenharmony_ci	}
10148c2ecf20Sopenharmony_ci
10158c2ecf20Sopenharmony_ci	/* 1 GiB/sec, slightly over IB SDR line rate */
10168c2ecf20Sopenharmony_ci	if (lcnt < (emsecs * 1024U))
10178c2ecf20Sopenharmony_ci		qib_dev_err(dd,
10188c2ecf20Sopenharmony_ci			    "Performance problem: bandwidth to PIO buffers is only %u MiB/sec\n",
10198c2ecf20Sopenharmony_ci			    lcnt / (u32) emsecs);
10208c2ecf20Sopenharmony_ci
10218c2ecf20Sopenharmony_ci	preempt_enable();
10228c2ecf20Sopenharmony_ci
10238c2ecf20Sopenharmony_ci	vfree(addr);
10248c2ecf20Sopenharmony_ci
10258c2ecf20Sopenharmony_cidone:
10268c2ecf20Sopenharmony_ci	/* disarm piobuf, so it's available again */
10278c2ecf20Sopenharmony_ci	dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_BUF(pbnum));
10288c2ecf20Sopenharmony_ci	qib_sendbuf_done(dd, pbnum);
10298c2ecf20Sopenharmony_ci	dd->f_set_armlaunch(dd, 1);
10308c2ecf20Sopenharmony_ci}
10318c2ecf20Sopenharmony_ci
10328c2ecf20Sopenharmony_civoid qib_free_devdata(struct qib_devdata *dd)
10338c2ecf20Sopenharmony_ci{
10348c2ecf20Sopenharmony_ci	unsigned long flags;
10358c2ecf20Sopenharmony_ci
10368c2ecf20Sopenharmony_ci	xa_lock_irqsave(&qib_dev_table, flags);
10378c2ecf20Sopenharmony_ci	__xa_erase(&qib_dev_table, dd->unit);
10388c2ecf20Sopenharmony_ci	xa_unlock_irqrestore(&qib_dev_table, flags);
10398c2ecf20Sopenharmony_ci
10408c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
10418c2ecf20Sopenharmony_ci	qib_dbg_ibdev_exit(&dd->verbs_dev);
10428c2ecf20Sopenharmony_ci#endif
10438c2ecf20Sopenharmony_ci	free_percpu(dd->int_counter);
10448c2ecf20Sopenharmony_ci	rvt_dealloc_device(&dd->verbs_dev.rdi);
10458c2ecf20Sopenharmony_ci}
10468c2ecf20Sopenharmony_ci
10478c2ecf20Sopenharmony_ciu64 qib_int_counter(struct qib_devdata *dd)
10488c2ecf20Sopenharmony_ci{
10498c2ecf20Sopenharmony_ci	int cpu;
10508c2ecf20Sopenharmony_ci	u64 int_counter = 0;
10518c2ecf20Sopenharmony_ci
10528c2ecf20Sopenharmony_ci	for_each_possible_cpu(cpu)
10538c2ecf20Sopenharmony_ci		int_counter += *per_cpu_ptr(dd->int_counter, cpu);
10548c2ecf20Sopenharmony_ci	return int_counter;
10558c2ecf20Sopenharmony_ci}
10568c2ecf20Sopenharmony_ci
10578c2ecf20Sopenharmony_ciu64 qib_sps_ints(void)
10588c2ecf20Sopenharmony_ci{
10598c2ecf20Sopenharmony_ci	unsigned long index, flags;
10608c2ecf20Sopenharmony_ci	struct qib_devdata *dd;
10618c2ecf20Sopenharmony_ci	u64 sps_ints = 0;
10628c2ecf20Sopenharmony_ci
10638c2ecf20Sopenharmony_ci	xa_lock_irqsave(&qib_dev_table, flags);
10648c2ecf20Sopenharmony_ci	xa_for_each(&qib_dev_table, index, dd) {
10658c2ecf20Sopenharmony_ci		sps_ints += qib_int_counter(dd);
10668c2ecf20Sopenharmony_ci	}
10678c2ecf20Sopenharmony_ci	xa_unlock_irqrestore(&qib_dev_table, flags);
10688c2ecf20Sopenharmony_ci	return sps_ints;
10698c2ecf20Sopenharmony_ci}
10708c2ecf20Sopenharmony_ci
10718c2ecf20Sopenharmony_ci/*
10728c2ecf20Sopenharmony_ci * Allocate our primary per-unit data structure.  Must be done via verbs
10738c2ecf20Sopenharmony_ci * allocator, because the verbs cleanup process both does cleanup and
10748c2ecf20Sopenharmony_ci * free of the data structure.
10758c2ecf20Sopenharmony_ci * "extra" is for chip-specific data.
10768c2ecf20Sopenharmony_ci */
10778c2ecf20Sopenharmony_cistruct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra)
10788c2ecf20Sopenharmony_ci{
10798c2ecf20Sopenharmony_ci	struct qib_devdata *dd;
10808c2ecf20Sopenharmony_ci	int ret, nports;
10818c2ecf20Sopenharmony_ci
10828c2ecf20Sopenharmony_ci	/* extra is * number of ports */
10838c2ecf20Sopenharmony_ci	nports = extra / sizeof(struct qib_pportdata);
10848c2ecf20Sopenharmony_ci	dd = (struct qib_devdata *)rvt_alloc_device(sizeof(*dd) + extra,
10858c2ecf20Sopenharmony_ci						    nports);
10868c2ecf20Sopenharmony_ci	if (!dd)
10878c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
10888c2ecf20Sopenharmony_ci
10898c2ecf20Sopenharmony_ci	ret = xa_alloc_irq(&qib_dev_table, &dd->unit, dd, xa_limit_32b,
10908c2ecf20Sopenharmony_ci			GFP_KERNEL);
10918c2ecf20Sopenharmony_ci	if (ret < 0) {
10928c2ecf20Sopenharmony_ci		qib_early_err(&pdev->dev,
10938c2ecf20Sopenharmony_ci			      "Could not allocate unit ID: error %d\n", -ret);
10948c2ecf20Sopenharmony_ci		goto bail;
10958c2ecf20Sopenharmony_ci	}
10968c2ecf20Sopenharmony_ci	rvt_set_ibdev_name(&dd->verbs_dev.rdi, "%s%d", "qib", dd->unit);
10978c2ecf20Sopenharmony_ci
10988c2ecf20Sopenharmony_ci	dd->int_counter = alloc_percpu(u64);
10998c2ecf20Sopenharmony_ci	if (!dd->int_counter) {
11008c2ecf20Sopenharmony_ci		ret = -ENOMEM;
11018c2ecf20Sopenharmony_ci		qib_early_err(&pdev->dev,
11028c2ecf20Sopenharmony_ci			      "Could not allocate per-cpu int_counter\n");
11038c2ecf20Sopenharmony_ci		goto bail;
11048c2ecf20Sopenharmony_ci	}
11058c2ecf20Sopenharmony_ci
11068c2ecf20Sopenharmony_ci	if (!qib_cpulist_count) {
11078c2ecf20Sopenharmony_ci		u32 count = num_online_cpus();
11088c2ecf20Sopenharmony_ci
11098c2ecf20Sopenharmony_ci		qib_cpulist = kcalloc(BITS_TO_LONGS(count), sizeof(long),
11108c2ecf20Sopenharmony_ci				      GFP_KERNEL);
11118c2ecf20Sopenharmony_ci		if (qib_cpulist)
11128c2ecf20Sopenharmony_ci			qib_cpulist_count = count;
11138c2ecf20Sopenharmony_ci	}
11148c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
11158c2ecf20Sopenharmony_ci	qib_dbg_ibdev_init(&dd->verbs_dev);
11168c2ecf20Sopenharmony_ci#endif
11178c2ecf20Sopenharmony_ci	return dd;
11188c2ecf20Sopenharmony_cibail:
11198c2ecf20Sopenharmony_ci	if (!list_empty(&dd->list))
11208c2ecf20Sopenharmony_ci		list_del_init(&dd->list);
11218c2ecf20Sopenharmony_ci	rvt_dealloc_device(&dd->verbs_dev.rdi);
11228c2ecf20Sopenharmony_ci	return ERR_PTR(ret);
11238c2ecf20Sopenharmony_ci}
11248c2ecf20Sopenharmony_ci
11258c2ecf20Sopenharmony_ci/*
11268c2ecf20Sopenharmony_ci * Called from freeze mode handlers, and from PCI error
11278c2ecf20Sopenharmony_ci * reporting code.  Should be paranoid about state of
11288c2ecf20Sopenharmony_ci * system and data structures.
11298c2ecf20Sopenharmony_ci */
11308c2ecf20Sopenharmony_civoid qib_disable_after_error(struct qib_devdata *dd)
11318c2ecf20Sopenharmony_ci{
11328c2ecf20Sopenharmony_ci	if (dd->flags & QIB_INITTED) {
11338c2ecf20Sopenharmony_ci		u32 pidx;
11348c2ecf20Sopenharmony_ci
11358c2ecf20Sopenharmony_ci		dd->flags &= ~QIB_INITTED;
11368c2ecf20Sopenharmony_ci		if (dd->pport)
11378c2ecf20Sopenharmony_ci			for (pidx = 0; pidx < dd->num_pports; ++pidx) {
11388c2ecf20Sopenharmony_ci				struct qib_pportdata *ppd;
11398c2ecf20Sopenharmony_ci
11408c2ecf20Sopenharmony_ci				ppd = dd->pport + pidx;
11418c2ecf20Sopenharmony_ci				if (dd->flags & QIB_PRESENT) {
11428c2ecf20Sopenharmony_ci					qib_set_linkstate(ppd,
11438c2ecf20Sopenharmony_ci						QIB_IB_LINKDOWN_DISABLE);
11448c2ecf20Sopenharmony_ci					dd->f_setextled(ppd, 0);
11458c2ecf20Sopenharmony_ci				}
11468c2ecf20Sopenharmony_ci				*ppd->statusp &= ~QIB_STATUS_IB_READY;
11478c2ecf20Sopenharmony_ci			}
11488c2ecf20Sopenharmony_ci	}
11498c2ecf20Sopenharmony_ci
11508c2ecf20Sopenharmony_ci	/*
11518c2ecf20Sopenharmony_ci	 * Mark as having had an error for driver, and also
11528c2ecf20Sopenharmony_ci	 * for /sys and status word mapped to user programs.
11538c2ecf20Sopenharmony_ci	 * This marks unit as not usable, until reset.
11548c2ecf20Sopenharmony_ci	 */
11558c2ecf20Sopenharmony_ci	if (dd->devstatusp)
11568c2ecf20Sopenharmony_ci		*dd->devstatusp |= QIB_STATUS_HWERROR;
11578c2ecf20Sopenharmony_ci}
11588c2ecf20Sopenharmony_ci
11598c2ecf20Sopenharmony_cistatic void qib_remove_one(struct pci_dev *);
11608c2ecf20Sopenharmony_cistatic int qib_init_one(struct pci_dev *, const struct pci_device_id *);
11618c2ecf20Sopenharmony_cistatic void qib_shutdown_one(struct pci_dev *);
11628c2ecf20Sopenharmony_ci
11638c2ecf20Sopenharmony_ci#define DRIVER_LOAD_MSG "Intel " QIB_DRV_NAME " loaded: "
11648c2ecf20Sopenharmony_ci#define PFX QIB_DRV_NAME ": "
11658c2ecf20Sopenharmony_ci
11668c2ecf20Sopenharmony_cistatic const struct pci_device_id qib_pci_tbl[] = {
11678c2ecf20Sopenharmony_ci	{ PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_QLOGIC_IB_6120) },
11688c2ecf20Sopenharmony_ci	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_IB_7220) },
11698c2ecf20Sopenharmony_ci	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_IB_7322) },
11708c2ecf20Sopenharmony_ci	{ 0, }
11718c2ecf20Sopenharmony_ci};
11728c2ecf20Sopenharmony_ci
11738c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(pci, qib_pci_tbl);
11748c2ecf20Sopenharmony_ci
11758c2ecf20Sopenharmony_cistatic struct pci_driver qib_driver = {
11768c2ecf20Sopenharmony_ci	.name = QIB_DRV_NAME,
11778c2ecf20Sopenharmony_ci	.probe = qib_init_one,
11788c2ecf20Sopenharmony_ci	.remove = qib_remove_one,
11798c2ecf20Sopenharmony_ci	.shutdown = qib_shutdown_one,
11808c2ecf20Sopenharmony_ci	.id_table = qib_pci_tbl,
11818c2ecf20Sopenharmony_ci	.err_handler = &qib_pci_err_handler,
11828c2ecf20Sopenharmony_ci};
11838c2ecf20Sopenharmony_ci
11848c2ecf20Sopenharmony_ci#ifdef CONFIG_INFINIBAND_QIB_DCA
11858c2ecf20Sopenharmony_ci
11868c2ecf20Sopenharmony_cistatic int qib_notify_dca(struct notifier_block *, unsigned long, void *);
11878c2ecf20Sopenharmony_cistatic struct notifier_block dca_notifier = {
11888c2ecf20Sopenharmony_ci	.notifier_call  = qib_notify_dca,
11898c2ecf20Sopenharmony_ci	.next           = NULL,
11908c2ecf20Sopenharmony_ci	.priority       = 0
11918c2ecf20Sopenharmony_ci};
11928c2ecf20Sopenharmony_ci
11938c2ecf20Sopenharmony_cistatic int qib_notify_dca_device(struct device *device, void *data)
11948c2ecf20Sopenharmony_ci{
11958c2ecf20Sopenharmony_ci	struct qib_devdata *dd = dev_get_drvdata(device);
11968c2ecf20Sopenharmony_ci	unsigned long event = *(unsigned long *)data;
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_ci	return dd->f_notify_dca(dd, event);
11998c2ecf20Sopenharmony_ci}
12008c2ecf20Sopenharmony_ci
12018c2ecf20Sopenharmony_cistatic int qib_notify_dca(struct notifier_block *nb, unsigned long event,
12028c2ecf20Sopenharmony_ci					  void *p)
12038c2ecf20Sopenharmony_ci{
12048c2ecf20Sopenharmony_ci	int rval;
12058c2ecf20Sopenharmony_ci
12068c2ecf20Sopenharmony_ci	rval = driver_for_each_device(&qib_driver.driver, NULL,
12078c2ecf20Sopenharmony_ci				      &event, qib_notify_dca_device);
12088c2ecf20Sopenharmony_ci	return rval ? NOTIFY_BAD : NOTIFY_DONE;
12098c2ecf20Sopenharmony_ci}
12108c2ecf20Sopenharmony_ci
12118c2ecf20Sopenharmony_ci#endif
12128c2ecf20Sopenharmony_ci
12138c2ecf20Sopenharmony_ci/*
12148c2ecf20Sopenharmony_ci * Do all the generic driver unit- and chip-independent memory
12158c2ecf20Sopenharmony_ci * allocation and initialization.
12168c2ecf20Sopenharmony_ci */
12178c2ecf20Sopenharmony_cistatic int __init qib_ib_init(void)
12188c2ecf20Sopenharmony_ci{
12198c2ecf20Sopenharmony_ci	int ret;
12208c2ecf20Sopenharmony_ci
12218c2ecf20Sopenharmony_ci	ret = qib_dev_init();
12228c2ecf20Sopenharmony_ci	if (ret)
12238c2ecf20Sopenharmony_ci		goto bail;
12248c2ecf20Sopenharmony_ci
12258c2ecf20Sopenharmony_ci	/*
12268c2ecf20Sopenharmony_ci	 * These must be called before the driver is registered with
12278c2ecf20Sopenharmony_ci	 * the PCI subsystem.
12288c2ecf20Sopenharmony_ci	 */
12298c2ecf20Sopenharmony_ci#ifdef CONFIG_INFINIBAND_QIB_DCA
12308c2ecf20Sopenharmony_ci	dca_register_notify(&dca_notifier);
12318c2ecf20Sopenharmony_ci#endif
12328c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
12338c2ecf20Sopenharmony_ci	qib_dbg_init();
12348c2ecf20Sopenharmony_ci#endif
12358c2ecf20Sopenharmony_ci	ret = pci_register_driver(&qib_driver);
12368c2ecf20Sopenharmony_ci	if (ret < 0) {
12378c2ecf20Sopenharmony_ci		pr_err("Unable to register driver: error %d\n", -ret);
12388c2ecf20Sopenharmony_ci		goto bail_dev;
12398c2ecf20Sopenharmony_ci	}
12408c2ecf20Sopenharmony_ci
12418c2ecf20Sopenharmony_ci	/* not fatal if it doesn't work */
12428c2ecf20Sopenharmony_ci	if (qib_init_qibfs())
12438c2ecf20Sopenharmony_ci		pr_err("Unable to register ipathfs\n");
12448c2ecf20Sopenharmony_ci	goto bail; /* all OK */
12458c2ecf20Sopenharmony_ci
12468c2ecf20Sopenharmony_cibail_dev:
12478c2ecf20Sopenharmony_ci#ifdef CONFIG_INFINIBAND_QIB_DCA
12488c2ecf20Sopenharmony_ci	dca_unregister_notify(&dca_notifier);
12498c2ecf20Sopenharmony_ci#endif
12508c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
12518c2ecf20Sopenharmony_ci	qib_dbg_exit();
12528c2ecf20Sopenharmony_ci#endif
12538c2ecf20Sopenharmony_ci	qib_dev_cleanup();
12548c2ecf20Sopenharmony_cibail:
12558c2ecf20Sopenharmony_ci	return ret;
12568c2ecf20Sopenharmony_ci}
12578c2ecf20Sopenharmony_ci
12588c2ecf20Sopenharmony_cimodule_init(qib_ib_init);
12598c2ecf20Sopenharmony_ci
12608c2ecf20Sopenharmony_ci/*
12618c2ecf20Sopenharmony_ci * Do the non-unit driver cleanup, memory free, etc. at unload.
12628c2ecf20Sopenharmony_ci */
12638c2ecf20Sopenharmony_cistatic void __exit qib_ib_cleanup(void)
12648c2ecf20Sopenharmony_ci{
12658c2ecf20Sopenharmony_ci	int ret;
12668c2ecf20Sopenharmony_ci
12678c2ecf20Sopenharmony_ci	ret = qib_exit_qibfs();
12688c2ecf20Sopenharmony_ci	if (ret)
12698c2ecf20Sopenharmony_ci		pr_err(
12708c2ecf20Sopenharmony_ci			"Unable to cleanup counter filesystem: error %d\n",
12718c2ecf20Sopenharmony_ci			-ret);
12728c2ecf20Sopenharmony_ci
12738c2ecf20Sopenharmony_ci#ifdef CONFIG_INFINIBAND_QIB_DCA
12748c2ecf20Sopenharmony_ci	dca_unregister_notify(&dca_notifier);
12758c2ecf20Sopenharmony_ci#endif
12768c2ecf20Sopenharmony_ci	pci_unregister_driver(&qib_driver);
12778c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
12788c2ecf20Sopenharmony_ci	qib_dbg_exit();
12798c2ecf20Sopenharmony_ci#endif
12808c2ecf20Sopenharmony_ci
12818c2ecf20Sopenharmony_ci	qib_cpulist_count = 0;
12828c2ecf20Sopenharmony_ci	kfree(qib_cpulist);
12838c2ecf20Sopenharmony_ci
12848c2ecf20Sopenharmony_ci	WARN_ON(!xa_empty(&qib_dev_table));
12858c2ecf20Sopenharmony_ci	qib_dev_cleanup();
12868c2ecf20Sopenharmony_ci}
12878c2ecf20Sopenharmony_ci
12888c2ecf20Sopenharmony_cimodule_exit(qib_ib_cleanup);
12898c2ecf20Sopenharmony_ci
12908c2ecf20Sopenharmony_ci/* this can only be called after a successful initialization */
12918c2ecf20Sopenharmony_cistatic void cleanup_device_data(struct qib_devdata *dd)
12928c2ecf20Sopenharmony_ci{
12938c2ecf20Sopenharmony_ci	int ctxt;
12948c2ecf20Sopenharmony_ci	int pidx;
12958c2ecf20Sopenharmony_ci	struct qib_ctxtdata **tmp;
12968c2ecf20Sopenharmony_ci	unsigned long flags;
12978c2ecf20Sopenharmony_ci
12988c2ecf20Sopenharmony_ci	/* users can't do anything more with chip */
12998c2ecf20Sopenharmony_ci	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
13008c2ecf20Sopenharmony_ci		if (dd->pport[pidx].statusp)
13018c2ecf20Sopenharmony_ci			*dd->pport[pidx].statusp &= ~QIB_STATUS_CHIP_PRESENT;
13028c2ecf20Sopenharmony_ci
13038c2ecf20Sopenharmony_ci		spin_lock(&dd->pport[pidx].cc_shadow_lock);
13048c2ecf20Sopenharmony_ci
13058c2ecf20Sopenharmony_ci		kfree(dd->pport[pidx].congestion_entries);
13068c2ecf20Sopenharmony_ci		dd->pport[pidx].congestion_entries = NULL;
13078c2ecf20Sopenharmony_ci		kfree(dd->pport[pidx].ccti_entries);
13088c2ecf20Sopenharmony_ci		dd->pport[pidx].ccti_entries = NULL;
13098c2ecf20Sopenharmony_ci		kfree(dd->pport[pidx].ccti_entries_shadow);
13108c2ecf20Sopenharmony_ci		dd->pport[pidx].ccti_entries_shadow = NULL;
13118c2ecf20Sopenharmony_ci		kfree(dd->pport[pidx].congestion_entries_shadow);
13128c2ecf20Sopenharmony_ci		dd->pport[pidx].congestion_entries_shadow = NULL;
13138c2ecf20Sopenharmony_ci
13148c2ecf20Sopenharmony_ci		spin_unlock(&dd->pport[pidx].cc_shadow_lock);
13158c2ecf20Sopenharmony_ci	}
13168c2ecf20Sopenharmony_ci
13178c2ecf20Sopenharmony_ci	qib_disable_wc(dd);
13188c2ecf20Sopenharmony_ci
13198c2ecf20Sopenharmony_ci	if (dd->pioavailregs_dma) {
13208c2ecf20Sopenharmony_ci		dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
13218c2ecf20Sopenharmony_ci				  (void *) dd->pioavailregs_dma,
13228c2ecf20Sopenharmony_ci				  dd->pioavailregs_phys);
13238c2ecf20Sopenharmony_ci		dd->pioavailregs_dma = NULL;
13248c2ecf20Sopenharmony_ci	}
13258c2ecf20Sopenharmony_ci
13268c2ecf20Sopenharmony_ci	if (dd->pageshadow) {
13278c2ecf20Sopenharmony_ci		struct page **tmpp = dd->pageshadow;
13288c2ecf20Sopenharmony_ci		dma_addr_t *tmpd = dd->physshadow;
13298c2ecf20Sopenharmony_ci		int i;
13308c2ecf20Sopenharmony_ci
13318c2ecf20Sopenharmony_ci		for (ctxt = 0; ctxt < dd->cfgctxts; ctxt++) {
13328c2ecf20Sopenharmony_ci			int ctxt_tidbase = ctxt * dd->rcvtidcnt;
13338c2ecf20Sopenharmony_ci			int maxtid = ctxt_tidbase + dd->rcvtidcnt;
13348c2ecf20Sopenharmony_ci
13358c2ecf20Sopenharmony_ci			for (i = ctxt_tidbase; i < maxtid; i++) {
13368c2ecf20Sopenharmony_ci				if (!tmpp[i])
13378c2ecf20Sopenharmony_ci					continue;
13388c2ecf20Sopenharmony_ci				pci_unmap_page(dd->pcidev, tmpd[i],
13398c2ecf20Sopenharmony_ci					       PAGE_SIZE, PCI_DMA_FROMDEVICE);
13408c2ecf20Sopenharmony_ci				qib_release_user_pages(&tmpp[i], 1);
13418c2ecf20Sopenharmony_ci				tmpp[i] = NULL;
13428c2ecf20Sopenharmony_ci			}
13438c2ecf20Sopenharmony_ci		}
13448c2ecf20Sopenharmony_ci
13458c2ecf20Sopenharmony_ci		dd->pageshadow = NULL;
13468c2ecf20Sopenharmony_ci		vfree(tmpp);
13478c2ecf20Sopenharmony_ci		dd->physshadow = NULL;
13488c2ecf20Sopenharmony_ci		vfree(tmpd);
13498c2ecf20Sopenharmony_ci	}
13508c2ecf20Sopenharmony_ci
13518c2ecf20Sopenharmony_ci	/*
13528c2ecf20Sopenharmony_ci	 * Free any resources still in use (usually just kernel contexts)
13538c2ecf20Sopenharmony_ci	 * at unload; we do for ctxtcnt, because that's what we allocate.
13548c2ecf20Sopenharmony_ci	 * We acquire lock to be really paranoid that rcd isn't being
13558c2ecf20Sopenharmony_ci	 * accessed from some interrupt-related code (that should not happen,
13568c2ecf20Sopenharmony_ci	 * but best to be sure).
13578c2ecf20Sopenharmony_ci	 */
13588c2ecf20Sopenharmony_ci	spin_lock_irqsave(&dd->uctxt_lock, flags);
13598c2ecf20Sopenharmony_ci	tmp = dd->rcd;
13608c2ecf20Sopenharmony_ci	dd->rcd = NULL;
13618c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&dd->uctxt_lock, flags);
13628c2ecf20Sopenharmony_ci	for (ctxt = 0; tmp && ctxt < dd->ctxtcnt; ctxt++) {
13638c2ecf20Sopenharmony_ci		struct qib_ctxtdata *rcd = tmp[ctxt];
13648c2ecf20Sopenharmony_ci
13658c2ecf20Sopenharmony_ci		tmp[ctxt] = NULL; /* debugging paranoia */
13668c2ecf20Sopenharmony_ci		qib_free_ctxtdata(dd, rcd);
13678c2ecf20Sopenharmony_ci	}
13688c2ecf20Sopenharmony_ci	kfree(tmp);
13698c2ecf20Sopenharmony_ci}
13708c2ecf20Sopenharmony_ci
13718c2ecf20Sopenharmony_ci/*
13728c2ecf20Sopenharmony_ci * Clean up on unit shutdown, or error during unit load after
13738c2ecf20Sopenharmony_ci * successful initialization.
13748c2ecf20Sopenharmony_ci */
13758c2ecf20Sopenharmony_cistatic void qib_postinit_cleanup(struct qib_devdata *dd)
13768c2ecf20Sopenharmony_ci{
13778c2ecf20Sopenharmony_ci	/*
13788c2ecf20Sopenharmony_ci	 * Clean up chip-specific stuff.
13798c2ecf20Sopenharmony_ci	 * We check for NULL here, because it's outside
13808c2ecf20Sopenharmony_ci	 * the kregbase check, and we need to call it
13818c2ecf20Sopenharmony_ci	 * after the free_irq.  Thus it's possible that
13828c2ecf20Sopenharmony_ci	 * the function pointers were never initialized.
13838c2ecf20Sopenharmony_ci	 */
13848c2ecf20Sopenharmony_ci	if (dd->f_cleanup)
13858c2ecf20Sopenharmony_ci		dd->f_cleanup(dd);
13868c2ecf20Sopenharmony_ci
13878c2ecf20Sopenharmony_ci	qib_pcie_ddcleanup(dd);
13888c2ecf20Sopenharmony_ci
13898c2ecf20Sopenharmony_ci	cleanup_device_data(dd);
13908c2ecf20Sopenharmony_ci
13918c2ecf20Sopenharmony_ci	qib_free_devdata(dd);
13928c2ecf20Sopenharmony_ci}
13938c2ecf20Sopenharmony_ci
13948c2ecf20Sopenharmony_cistatic int qib_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
13958c2ecf20Sopenharmony_ci{
13968c2ecf20Sopenharmony_ci	int ret, j, pidx, initfail;
13978c2ecf20Sopenharmony_ci	struct qib_devdata *dd = NULL;
13988c2ecf20Sopenharmony_ci
13998c2ecf20Sopenharmony_ci	ret = qib_pcie_init(pdev, ent);
14008c2ecf20Sopenharmony_ci	if (ret)
14018c2ecf20Sopenharmony_ci		goto bail;
14028c2ecf20Sopenharmony_ci
14038c2ecf20Sopenharmony_ci	/*
14048c2ecf20Sopenharmony_ci	 * Do device-specific initialiation, function table setup, dd
14058c2ecf20Sopenharmony_ci	 * allocation, etc.
14068c2ecf20Sopenharmony_ci	 */
14078c2ecf20Sopenharmony_ci	switch (ent->device) {
14088c2ecf20Sopenharmony_ci	case PCI_DEVICE_ID_QLOGIC_IB_6120:
14098c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_MSI
14108c2ecf20Sopenharmony_ci		dd = qib_init_iba6120_funcs(pdev, ent);
14118c2ecf20Sopenharmony_ci#else
14128c2ecf20Sopenharmony_ci		qib_early_err(&pdev->dev,
14138c2ecf20Sopenharmony_ci			"Intel PCIE device 0x%x cannot work if CONFIG_PCI_MSI is not enabled\n",
14148c2ecf20Sopenharmony_ci			ent->device);
14158c2ecf20Sopenharmony_ci		dd = ERR_PTR(-ENODEV);
14168c2ecf20Sopenharmony_ci#endif
14178c2ecf20Sopenharmony_ci		break;
14188c2ecf20Sopenharmony_ci
14198c2ecf20Sopenharmony_ci	case PCI_DEVICE_ID_QLOGIC_IB_7220:
14208c2ecf20Sopenharmony_ci		dd = qib_init_iba7220_funcs(pdev, ent);
14218c2ecf20Sopenharmony_ci		break;
14228c2ecf20Sopenharmony_ci
14238c2ecf20Sopenharmony_ci	case PCI_DEVICE_ID_QLOGIC_IB_7322:
14248c2ecf20Sopenharmony_ci		dd = qib_init_iba7322_funcs(pdev, ent);
14258c2ecf20Sopenharmony_ci		break;
14268c2ecf20Sopenharmony_ci
14278c2ecf20Sopenharmony_ci	default:
14288c2ecf20Sopenharmony_ci		qib_early_err(&pdev->dev,
14298c2ecf20Sopenharmony_ci			"Failing on unknown Intel deviceid 0x%x\n",
14308c2ecf20Sopenharmony_ci			ent->device);
14318c2ecf20Sopenharmony_ci		ret = -ENODEV;
14328c2ecf20Sopenharmony_ci	}
14338c2ecf20Sopenharmony_ci
14348c2ecf20Sopenharmony_ci	if (IS_ERR(dd))
14358c2ecf20Sopenharmony_ci		ret = PTR_ERR(dd);
14368c2ecf20Sopenharmony_ci	if (ret)
14378c2ecf20Sopenharmony_ci		goto bail; /* error already printed */
14388c2ecf20Sopenharmony_ci
14398c2ecf20Sopenharmony_ci	ret = qib_create_workqueues(dd);
14408c2ecf20Sopenharmony_ci	if (ret)
14418c2ecf20Sopenharmony_ci		goto bail;
14428c2ecf20Sopenharmony_ci
14438c2ecf20Sopenharmony_ci	/* do the generic initialization */
14448c2ecf20Sopenharmony_ci	initfail = qib_init(dd, 0);
14458c2ecf20Sopenharmony_ci
14468c2ecf20Sopenharmony_ci	ret = qib_register_ib_device(dd);
14478c2ecf20Sopenharmony_ci
14488c2ecf20Sopenharmony_ci	/*
14498c2ecf20Sopenharmony_ci	 * Now ready for use.  this should be cleared whenever we
14508c2ecf20Sopenharmony_ci	 * detect a reset, or initiate one.  If earlier failure,
14518c2ecf20Sopenharmony_ci	 * we still create devices, so diags, etc. can be used
14528c2ecf20Sopenharmony_ci	 * to determine cause of problem.
14538c2ecf20Sopenharmony_ci	 */
14548c2ecf20Sopenharmony_ci	if (!qib_mini_init && !initfail && !ret)
14558c2ecf20Sopenharmony_ci		dd->flags |= QIB_INITTED;
14568c2ecf20Sopenharmony_ci
14578c2ecf20Sopenharmony_ci	j = qib_device_create(dd);
14588c2ecf20Sopenharmony_ci	if (j)
14598c2ecf20Sopenharmony_ci		qib_dev_err(dd, "Failed to create /dev devices: %d\n", -j);
14608c2ecf20Sopenharmony_ci	j = qibfs_add(dd);
14618c2ecf20Sopenharmony_ci	if (j)
14628c2ecf20Sopenharmony_ci		qib_dev_err(dd, "Failed filesystem setup for counters: %d\n",
14638c2ecf20Sopenharmony_ci			    -j);
14648c2ecf20Sopenharmony_ci
14658c2ecf20Sopenharmony_ci	if (qib_mini_init || initfail || ret) {
14668c2ecf20Sopenharmony_ci		qib_stop_timers(dd);
14678c2ecf20Sopenharmony_ci		flush_workqueue(ib_wq);
14688c2ecf20Sopenharmony_ci		for (pidx = 0; pidx < dd->num_pports; ++pidx)
14698c2ecf20Sopenharmony_ci			dd->f_quiet_serdes(dd->pport + pidx);
14708c2ecf20Sopenharmony_ci		if (qib_mini_init)
14718c2ecf20Sopenharmony_ci			goto bail;
14728c2ecf20Sopenharmony_ci		if (!j) {
14738c2ecf20Sopenharmony_ci			(void) qibfs_remove(dd);
14748c2ecf20Sopenharmony_ci			qib_device_remove(dd);
14758c2ecf20Sopenharmony_ci		}
14768c2ecf20Sopenharmony_ci		if (!ret)
14778c2ecf20Sopenharmony_ci			qib_unregister_ib_device(dd);
14788c2ecf20Sopenharmony_ci		qib_postinit_cleanup(dd);
14798c2ecf20Sopenharmony_ci		if (initfail)
14808c2ecf20Sopenharmony_ci			ret = initfail;
14818c2ecf20Sopenharmony_ci		goto bail;
14828c2ecf20Sopenharmony_ci	}
14838c2ecf20Sopenharmony_ci
14848c2ecf20Sopenharmony_ci	ret = qib_enable_wc(dd);
14858c2ecf20Sopenharmony_ci	if (ret) {
14868c2ecf20Sopenharmony_ci		qib_dev_err(dd,
14878c2ecf20Sopenharmony_ci			"Write combining not enabled (err %d): performance may be poor\n",
14888c2ecf20Sopenharmony_ci			-ret);
14898c2ecf20Sopenharmony_ci		ret = 0;
14908c2ecf20Sopenharmony_ci	}
14918c2ecf20Sopenharmony_ci
14928c2ecf20Sopenharmony_ci	qib_verify_pioperf(dd);
14938c2ecf20Sopenharmony_cibail:
14948c2ecf20Sopenharmony_ci	return ret;
14958c2ecf20Sopenharmony_ci}
14968c2ecf20Sopenharmony_ci
14978c2ecf20Sopenharmony_cistatic void qib_remove_one(struct pci_dev *pdev)
14988c2ecf20Sopenharmony_ci{
14998c2ecf20Sopenharmony_ci	struct qib_devdata *dd = pci_get_drvdata(pdev);
15008c2ecf20Sopenharmony_ci	int ret;
15018c2ecf20Sopenharmony_ci
15028c2ecf20Sopenharmony_ci	/* unregister from IB core */
15038c2ecf20Sopenharmony_ci	qib_unregister_ib_device(dd);
15048c2ecf20Sopenharmony_ci
15058c2ecf20Sopenharmony_ci	/*
15068c2ecf20Sopenharmony_ci	 * Disable the IB link, disable interrupts on the device,
15078c2ecf20Sopenharmony_ci	 * clear dma engines, etc.
15088c2ecf20Sopenharmony_ci	 */
15098c2ecf20Sopenharmony_ci	if (!qib_mini_init)
15108c2ecf20Sopenharmony_ci		qib_shutdown_device(dd);
15118c2ecf20Sopenharmony_ci
15128c2ecf20Sopenharmony_ci	qib_stop_timers(dd);
15138c2ecf20Sopenharmony_ci
15148c2ecf20Sopenharmony_ci	/* wait until all of our (qsfp) queue_work() calls complete */
15158c2ecf20Sopenharmony_ci	flush_workqueue(ib_wq);
15168c2ecf20Sopenharmony_ci
15178c2ecf20Sopenharmony_ci	ret = qibfs_remove(dd);
15188c2ecf20Sopenharmony_ci	if (ret)
15198c2ecf20Sopenharmony_ci		qib_dev_err(dd, "Failed counters filesystem cleanup: %d\n",
15208c2ecf20Sopenharmony_ci			    -ret);
15218c2ecf20Sopenharmony_ci
15228c2ecf20Sopenharmony_ci	qib_device_remove(dd);
15238c2ecf20Sopenharmony_ci
15248c2ecf20Sopenharmony_ci	qib_postinit_cleanup(dd);
15258c2ecf20Sopenharmony_ci}
15268c2ecf20Sopenharmony_ci
15278c2ecf20Sopenharmony_cistatic void qib_shutdown_one(struct pci_dev *pdev)
15288c2ecf20Sopenharmony_ci{
15298c2ecf20Sopenharmony_ci	struct qib_devdata *dd = pci_get_drvdata(pdev);
15308c2ecf20Sopenharmony_ci
15318c2ecf20Sopenharmony_ci	qib_shutdown_device(dd);
15328c2ecf20Sopenharmony_ci}
15338c2ecf20Sopenharmony_ci
15348c2ecf20Sopenharmony_ci/**
15358c2ecf20Sopenharmony_ci * qib_create_rcvhdrq - create a receive header queue
15368c2ecf20Sopenharmony_ci * @dd: the qlogic_ib device
15378c2ecf20Sopenharmony_ci * @rcd: the context data
15388c2ecf20Sopenharmony_ci *
15398c2ecf20Sopenharmony_ci * This must be contiguous memory (from an i/o perspective), and must be
15408c2ecf20Sopenharmony_ci * DMA'able (which means for some systems, it will go through an IOMMU,
15418c2ecf20Sopenharmony_ci * or be forced into a low address range).
15428c2ecf20Sopenharmony_ci */
15438c2ecf20Sopenharmony_ciint qib_create_rcvhdrq(struct qib_devdata *dd, struct qib_ctxtdata *rcd)
15448c2ecf20Sopenharmony_ci{
15458c2ecf20Sopenharmony_ci	unsigned amt;
15468c2ecf20Sopenharmony_ci	int old_node_id;
15478c2ecf20Sopenharmony_ci
15488c2ecf20Sopenharmony_ci	if (!rcd->rcvhdrq) {
15498c2ecf20Sopenharmony_ci		dma_addr_t phys_hdrqtail;
15508c2ecf20Sopenharmony_ci		gfp_t gfp_flags;
15518c2ecf20Sopenharmony_ci
15528c2ecf20Sopenharmony_ci		amt = ALIGN(dd->rcvhdrcnt * dd->rcvhdrentsize *
15538c2ecf20Sopenharmony_ci			    sizeof(u32), PAGE_SIZE);
15548c2ecf20Sopenharmony_ci		gfp_flags = (rcd->ctxt >= dd->first_user_ctxt) ?
15558c2ecf20Sopenharmony_ci			GFP_USER : GFP_KERNEL;
15568c2ecf20Sopenharmony_ci
15578c2ecf20Sopenharmony_ci		old_node_id = dev_to_node(&dd->pcidev->dev);
15588c2ecf20Sopenharmony_ci		set_dev_node(&dd->pcidev->dev, rcd->node_id);
15598c2ecf20Sopenharmony_ci		rcd->rcvhdrq = dma_alloc_coherent(
15608c2ecf20Sopenharmony_ci			&dd->pcidev->dev, amt, &rcd->rcvhdrq_phys,
15618c2ecf20Sopenharmony_ci			gfp_flags | __GFP_COMP);
15628c2ecf20Sopenharmony_ci		set_dev_node(&dd->pcidev->dev, old_node_id);
15638c2ecf20Sopenharmony_ci
15648c2ecf20Sopenharmony_ci		if (!rcd->rcvhdrq) {
15658c2ecf20Sopenharmony_ci			qib_dev_err(dd,
15668c2ecf20Sopenharmony_ci				"attempt to allocate %d bytes for ctxt %u rcvhdrq failed\n",
15678c2ecf20Sopenharmony_ci				amt, rcd->ctxt);
15688c2ecf20Sopenharmony_ci			goto bail;
15698c2ecf20Sopenharmony_ci		}
15708c2ecf20Sopenharmony_ci
15718c2ecf20Sopenharmony_ci		if (rcd->ctxt >= dd->first_user_ctxt) {
15728c2ecf20Sopenharmony_ci			rcd->user_event_mask = vmalloc_user(PAGE_SIZE);
15738c2ecf20Sopenharmony_ci			if (!rcd->user_event_mask)
15748c2ecf20Sopenharmony_ci				goto bail_free_hdrq;
15758c2ecf20Sopenharmony_ci		}
15768c2ecf20Sopenharmony_ci
15778c2ecf20Sopenharmony_ci		if (!(dd->flags & QIB_NODMA_RTAIL)) {
15788c2ecf20Sopenharmony_ci			set_dev_node(&dd->pcidev->dev, rcd->node_id);
15798c2ecf20Sopenharmony_ci			rcd->rcvhdrtail_kvaddr = dma_alloc_coherent(
15808c2ecf20Sopenharmony_ci				&dd->pcidev->dev, PAGE_SIZE, &phys_hdrqtail,
15818c2ecf20Sopenharmony_ci				gfp_flags);
15828c2ecf20Sopenharmony_ci			set_dev_node(&dd->pcidev->dev, old_node_id);
15838c2ecf20Sopenharmony_ci			if (!rcd->rcvhdrtail_kvaddr)
15848c2ecf20Sopenharmony_ci				goto bail_free;
15858c2ecf20Sopenharmony_ci			rcd->rcvhdrqtailaddr_phys = phys_hdrqtail;
15868c2ecf20Sopenharmony_ci		}
15878c2ecf20Sopenharmony_ci
15888c2ecf20Sopenharmony_ci		rcd->rcvhdrq_size = amt;
15898c2ecf20Sopenharmony_ci	}
15908c2ecf20Sopenharmony_ci
15918c2ecf20Sopenharmony_ci	/* clear for security and sanity on each use */
15928c2ecf20Sopenharmony_ci	memset(rcd->rcvhdrq, 0, rcd->rcvhdrq_size);
15938c2ecf20Sopenharmony_ci	if (rcd->rcvhdrtail_kvaddr)
15948c2ecf20Sopenharmony_ci		memset(rcd->rcvhdrtail_kvaddr, 0, PAGE_SIZE);
15958c2ecf20Sopenharmony_ci	return 0;
15968c2ecf20Sopenharmony_ci
15978c2ecf20Sopenharmony_cibail_free:
15988c2ecf20Sopenharmony_ci	qib_dev_err(dd,
15998c2ecf20Sopenharmony_ci		"attempt to allocate 1 page for ctxt %u rcvhdrqtailaddr failed\n",
16008c2ecf20Sopenharmony_ci		rcd->ctxt);
16018c2ecf20Sopenharmony_ci	vfree(rcd->user_event_mask);
16028c2ecf20Sopenharmony_ci	rcd->user_event_mask = NULL;
16038c2ecf20Sopenharmony_cibail_free_hdrq:
16048c2ecf20Sopenharmony_ci	dma_free_coherent(&dd->pcidev->dev, amt, rcd->rcvhdrq,
16058c2ecf20Sopenharmony_ci			  rcd->rcvhdrq_phys);
16068c2ecf20Sopenharmony_ci	rcd->rcvhdrq = NULL;
16078c2ecf20Sopenharmony_cibail:
16088c2ecf20Sopenharmony_ci	return -ENOMEM;
16098c2ecf20Sopenharmony_ci}
16108c2ecf20Sopenharmony_ci
16118c2ecf20Sopenharmony_ci/**
16128c2ecf20Sopenharmony_ci * allocate eager buffers, both kernel and user contexts.
16138c2ecf20Sopenharmony_ci * @rcd: the context we are setting up.
16148c2ecf20Sopenharmony_ci *
16158c2ecf20Sopenharmony_ci * Allocate the eager TID buffers and program them into hip.
16168c2ecf20Sopenharmony_ci * They are no longer completely contiguous, we do multiple allocation
16178c2ecf20Sopenharmony_ci * calls.  Otherwise we get the OOM code involved, by asking for too
16188c2ecf20Sopenharmony_ci * much per call, with disastrous results on some kernels.
16198c2ecf20Sopenharmony_ci */
16208c2ecf20Sopenharmony_ciint qib_setup_eagerbufs(struct qib_ctxtdata *rcd)
16218c2ecf20Sopenharmony_ci{
16228c2ecf20Sopenharmony_ci	struct qib_devdata *dd = rcd->dd;
16238c2ecf20Sopenharmony_ci	unsigned e, egrcnt, egrperchunk, chunk, egrsize, egroff;
16248c2ecf20Sopenharmony_ci	size_t size;
16258c2ecf20Sopenharmony_ci	gfp_t gfp_flags;
16268c2ecf20Sopenharmony_ci	int old_node_id;
16278c2ecf20Sopenharmony_ci
16288c2ecf20Sopenharmony_ci	/*
16298c2ecf20Sopenharmony_ci	 * GFP_USER, but without GFP_FS, so buffer cache can be
16308c2ecf20Sopenharmony_ci	 * coalesced (we hope); otherwise, even at order 4,
16318c2ecf20Sopenharmony_ci	 * heavy filesystem activity makes these fail, and we can
16328c2ecf20Sopenharmony_ci	 * use compound pages.
16338c2ecf20Sopenharmony_ci	 */
16348c2ecf20Sopenharmony_ci	gfp_flags = __GFP_RECLAIM | __GFP_IO | __GFP_COMP;
16358c2ecf20Sopenharmony_ci
16368c2ecf20Sopenharmony_ci	egrcnt = rcd->rcvegrcnt;
16378c2ecf20Sopenharmony_ci	egroff = rcd->rcvegr_tid_base;
16388c2ecf20Sopenharmony_ci	egrsize = dd->rcvegrbufsize;
16398c2ecf20Sopenharmony_ci
16408c2ecf20Sopenharmony_ci	chunk = rcd->rcvegrbuf_chunks;
16418c2ecf20Sopenharmony_ci	egrperchunk = rcd->rcvegrbufs_perchunk;
16428c2ecf20Sopenharmony_ci	size = rcd->rcvegrbuf_size;
16438c2ecf20Sopenharmony_ci	if (!rcd->rcvegrbuf) {
16448c2ecf20Sopenharmony_ci		rcd->rcvegrbuf =
16458c2ecf20Sopenharmony_ci			kcalloc_node(chunk, sizeof(rcd->rcvegrbuf[0]),
16468c2ecf20Sopenharmony_ci				     GFP_KERNEL, rcd->node_id);
16478c2ecf20Sopenharmony_ci		if (!rcd->rcvegrbuf)
16488c2ecf20Sopenharmony_ci			goto bail;
16498c2ecf20Sopenharmony_ci	}
16508c2ecf20Sopenharmony_ci	if (!rcd->rcvegrbuf_phys) {
16518c2ecf20Sopenharmony_ci		rcd->rcvegrbuf_phys =
16528c2ecf20Sopenharmony_ci			kmalloc_array_node(chunk,
16538c2ecf20Sopenharmony_ci					   sizeof(rcd->rcvegrbuf_phys[0]),
16548c2ecf20Sopenharmony_ci					   GFP_KERNEL, rcd->node_id);
16558c2ecf20Sopenharmony_ci		if (!rcd->rcvegrbuf_phys)
16568c2ecf20Sopenharmony_ci			goto bail_rcvegrbuf;
16578c2ecf20Sopenharmony_ci	}
16588c2ecf20Sopenharmony_ci	for (e = 0; e < rcd->rcvegrbuf_chunks; e++) {
16598c2ecf20Sopenharmony_ci		if (rcd->rcvegrbuf[e])
16608c2ecf20Sopenharmony_ci			continue;
16618c2ecf20Sopenharmony_ci
16628c2ecf20Sopenharmony_ci		old_node_id = dev_to_node(&dd->pcidev->dev);
16638c2ecf20Sopenharmony_ci		set_dev_node(&dd->pcidev->dev, rcd->node_id);
16648c2ecf20Sopenharmony_ci		rcd->rcvegrbuf[e] =
16658c2ecf20Sopenharmony_ci			dma_alloc_coherent(&dd->pcidev->dev, size,
16668c2ecf20Sopenharmony_ci					   &rcd->rcvegrbuf_phys[e],
16678c2ecf20Sopenharmony_ci					   gfp_flags);
16688c2ecf20Sopenharmony_ci		set_dev_node(&dd->pcidev->dev, old_node_id);
16698c2ecf20Sopenharmony_ci		if (!rcd->rcvegrbuf[e])
16708c2ecf20Sopenharmony_ci			goto bail_rcvegrbuf_phys;
16718c2ecf20Sopenharmony_ci	}
16728c2ecf20Sopenharmony_ci
16738c2ecf20Sopenharmony_ci	rcd->rcvegr_phys = rcd->rcvegrbuf_phys[0];
16748c2ecf20Sopenharmony_ci
16758c2ecf20Sopenharmony_ci	for (e = chunk = 0; chunk < rcd->rcvegrbuf_chunks; chunk++) {
16768c2ecf20Sopenharmony_ci		dma_addr_t pa = rcd->rcvegrbuf_phys[chunk];
16778c2ecf20Sopenharmony_ci		unsigned i;
16788c2ecf20Sopenharmony_ci
16798c2ecf20Sopenharmony_ci		/* clear for security and sanity on each use */
16808c2ecf20Sopenharmony_ci		memset(rcd->rcvegrbuf[chunk], 0, size);
16818c2ecf20Sopenharmony_ci
16828c2ecf20Sopenharmony_ci		for (i = 0; e < egrcnt && i < egrperchunk; e++, i++) {
16838c2ecf20Sopenharmony_ci			dd->f_put_tid(dd, e + egroff +
16848c2ecf20Sopenharmony_ci					  (u64 __iomem *)
16858c2ecf20Sopenharmony_ci					  ((char __iomem *)
16868c2ecf20Sopenharmony_ci					   dd->kregbase +
16878c2ecf20Sopenharmony_ci					   dd->rcvegrbase),
16888c2ecf20Sopenharmony_ci					  RCVHQ_RCV_TYPE_EAGER, pa);
16898c2ecf20Sopenharmony_ci			pa += egrsize;
16908c2ecf20Sopenharmony_ci		}
16918c2ecf20Sopenharmony_ci		cond_resched(); /* don't hog the cpu */
16928c2ecf20Sopenharmony_ci	}
16938c2ecf20Sopenharmony_ci
16948c2ecf20Sopenharmony_ci	return 0;
16958c2ecf20Sopenharmony_ci
16968c2ecf20Sopenharmony_cibail_rcvegrbuf_phys:
16978c2ecf20Sopenharmony_ci	for (e = 0; e < rcd->rcvegrbuf_chunks && rcd->rcvegrbuf[e]; e++)
16988c2ecf20Sopenharmony_ci		dma_free_coherent(&dd->pcidev->dev, size,
16998c2ecf20Sopenharmony_ci				  rcd->rcvegrbuf[e], rcd->rcvegrbuf_phys[e]);
17008c2ecf20Sopenharmony_ci	kfree(rcd->rcvegrbuf_phys);
17018c2ecf20Sopenharmony_ci	rcd->rcvegrbuf_phys = NULL;
17028c2ecf20Sopenharmony_cibail_rcvegrbuf:
17038c2ecf20Sopenharmony_ci	kfree(rcd->rcvegrbuf);
17048c2ecf20Sopenharmony_ci	rcd->rcvegrbuf = NULL;
17058c2ecf20Sopenharmony_cibail:
17068c2ecf20Sopenharmony_ci	return -ENOMEM;
17078c2ecf20Sopenharmony_ci}
17088c2ecf20Sopenharmony_ci
17098c2ecf20Sopenharmony_ci/*
17108c2ecf20Sopenharmony_ci * Note: Changes to this routine should be mirrored
17118c2ecf20Sopenharmony_ci * for the diagnostics routine qib_remap_ioaddr32().
17128c2ecf20Sopenharmony_ci * There is also related code for VL15 buffers in qib_init_7322_variables().
17138c2ecf20Sopenharmony_ci * The teardown code that unmaps is in qib_pcie_ddcleanup()
17148c2ecf20Sopenharmony_ci */
17158c2ecf20Sopenharmony_ciint init_chip_wc_pat(struct qib_devdata *dd, u32 vl15buflen)
17168c2ecf20Sopenharmony_ci{
17178c2ecf20Sopenharmony_ci	u64 __iomem *qib_kregbase = NULL;
17188c2ecf20Sopenharmony_ci	void __iomem *qib_piobase = NULL;
17198c2ecf20Sopenharmony_ci	u64 __iomem *qib_userbase = NULL;
17208c2ecf20Sopenharmony_ci	u64 qib_kreglen;
17218c2ecf20Sopenharmony_ci	u64 qib_pio2koffset = dd->piobufbase & 0xffffffff;
17228c2ecf20Sopenharmony_ci	u64 qib_pio4koffset = dd->piobufbase >> 32;
17238c2ecf20Sopenharmony_ci	u64 qib_pio2klen = dd->piobcnt2k * dd->palign;
17248c2ecf20Sopenharmony_ci	u64 qib_pio4klen = dd->piobcnt4k * dd->align4k;
17258c2ecf20Sopenharmony_ci	u64 qib_physaddr = dd->physaddr;
17268c2ecf20Sopenharmony_ci	u64 qib_piolen;
17278c2ecf20Sopenharmony_ci	u64 qib_userlen = 0;
17288c2ecf20Sopenharmony_ci
17298c2ecf20Sopenharmony_ci	/*
17308c2ecf20Sopenharmony_ci	 * Free the old mapping because the kernel will try to reuse the
17318c2ecf20Sopenharmony_ci	 * old mapping and not create a new mapping with the
17328c2ecf20Sopenharmony_ci	 * write combining attribute.
17338c2ecf20Sopenharmony_ci	 */
17348c2ecf20Sopenharmony_ci	iounmap(dd->kregbase);
17358c2ecf20Sopenharmony_ci	dd->kregbase = NULL;
17368c2ecf20Sopenharmony_ci
17378c2ecf20Sopenharmony_ci	/*
17388c2ecf20Sopenharmony_ci	 * Assumes chip address space looks like:
17398c2ecf20Sopenharmony_ci	 *	- kregs + sregs + cregs + uregs (in any order)
17408c2ecf20Sopenharmony_ci	 *	- piobufs (2K and 4K bufs in either order)
17418c2ecf20Sopenharmony_ci	 * or:
17428c2ecf20Sopenharmony_ci	 *	- kregs + sregs + cregs (in any order)
17438c2ecf20Sopenharmony_ci	 *	- piobufs (2K and 4K bufs in either order)
17448c2ecf20Sopenharmony_ci	 *	- uregs
17458c2ecf20Sopenharmony_ci	 */
17468c2ecf20Sopenharmony_ci	if (dd->piobcnt4k == 0) {
17478c2ecf20Sopenharmony_ci		qib_kreglen = qib_pio2koffset;
17488c2ecf20Sopenharmony_ci		qib_piolen = qib_pio2klen;
17498c2ecf20Sopenharmony_ci	} else if (qib_pio2koffset < qib_pio4koffset) {
17508c2ecf20Sopenharmony_ci		qib_kreglen = qib_pio2koffset;
17518c2ecf20Sopenharmony_ci		qib_piolen = qib_pio4koffset + qib_pio4klen - qib_kreglen;
17528c2ecf20Sopenharmony_ci	} else {
17538c2ecf20Sopenharmony_ci		qib_kreglen = qib_pio4koffset;
17548c2ecf20Sopenharmony_ci		qib_piolen = qib_pio2koffset + qib_pio2klen - qib_kreglen;
17558c2ecf20Sopenharmony_ci	}
17568c2ecf20Sopenharmony_ci	qib_piolen += vl15buflen;
17578c2ecf20Sopenharmony_ci	/* Map just the configured ports (not all hw ports) */
17588c2ecf20Sopenharmony_ci	if (dd->uregbase > qib_kreglen)
17598c2ecf20Sopenharmony_ci		qib_userlen = dd->ureg_align * dd->cfgctxts;
17608c2ecf20Sopenharmony_ci
17618c2ecf20Sopenharmony_ci	/* Sanity checks passed, now create the new mappings */
17628c2ecf20Sopenharmony_ci	qib_kregbase = ioremap(qib_physaddr, qib_kreglen);
17638c2ecf20Sopenharmony_ci	if (!qib_kregbase)
17648c2ecf20Sopenharmony_ci		goto bail;
17658c2ecf20Sopenharmony_ci
17668c2ecf20Sopenharmony_ci	qib_piobase = ioremap_wc(qib_physaddr + qib_kreglen, qib_piolen);
17678c2ecf20Sopenharmony_ci	if (!qib_piobase)
17688c2ecf20Sopenharmony_ci		goto bail_kregbase;
17698c2ecf20Sopenharmony_ci
17708c2ecf20Sopenharmony_ci	if (qib_userlen) {
17718c2ecf20Sopenharmony_ci		qib_userbase = ioremap(qib_physaddr + dd->uregbase,
17728c2ecf20Sopenharmony_ci					       qib_userlen);
17738c2ecf20Sopenharmony_ci		if (!qib_userbase)
17748c2ecf20Sopenharmony_ci			goto bail_piobase;
17758c2ecf20Sopenharmony_ci	}
17768c2ecf20Sopenharmony_ci
17778c2ecf20Sopenharmony_ci	dd->kregbase = qib_kregbase;
17788c2ecf20Sopenharmony_ci	dd->kregend = (u64 __iomem *)
17798c2ecf20Sopenharmony_ci		((char __iomem *) qib_kregbase + qib_kreglen);
17808c2ecf20Sopenharmony_ci	dd->piobase = qib_piobase;
17818c2ecf20Sopenharmony_ci	dd->pio2kbase = (void __iomem *)
17828c2ecf20Sopenharmony_ci		(((char __iomem *) dd->piobase) +
17838c2ecf20Sopenharmony_ci		 qib_pio2koffset - qib_kreglen);
17848c2ecf20Sopenharmony_ci	if (dd->piobcnt4k)
17858c2ecf20Sopenharmony_ci		dd->pio4kbase = (void __iomem *)
17868c2ecf20Sopenharmony_ci			(((char __iomem *) dd->piobase) +
17878c2ecf20Sopenharmony_ci			 qib_pio4koffset - qib_kreglen);
17888c2ecf20Sopenharmony_ci	if (qib_userlen)
17898c2ecf20Sopenharmony_ci		/* ureg will now be accessed relative to dd->userbase */
17908c2ecf20Sopenharmony_ci		dd->userbase = qib_userbase;
17918c2ecf20Sopenharmony_ci	return 0;
17928c2ecf20Sopenharmony_ci
17938c2ecf20Sopenharmony_cibail_piobase:
17948c2ecf20Sopenharmony_ci	iounmap(qib_piobase);
17958c2ecf20Sopenharmony_cibail_kregbase:
17968c2ecf20Sopenharmony_ci	iounmap(qib_kregbase);
17978c2ecf20Sopenharmony_cibail:
17988c2ecf20Sopenharmony_ci	return -ENOMEM;
17998c2ecf20Sopenharmony_ci}
1800