1fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick/*
2fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  IBM eServer eHCA Infiniband device driver for Linux on POWER
3fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
4fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  module start stop, hca detection
5fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
6fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  Authors: Heiko J Schick <schickhj@de.ibm.com>
7fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *           Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *           Joachim Fenkes <fenkes@de.ibm.com>
9fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
10fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  Copyright (c) 2005 IBM Corporation
11fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
12fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  All rights reserved.
13fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
14fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  This source code is distributed under a dual license of GPL v2.0 and OpenIB
15fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  BSD.
16fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
17fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * OpenIB BSD License
18fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
19fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistribution and use in source and binary forms, with or without
20fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * modification, are permitted provided that the following conditions are met:
21fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
22fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistributions of source code must retain the above copyright notice, this
23fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * list of conditions and the following disclaimer.
24fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
25fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistributions in binary form must reproduce the above copyright notice,
26fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * this list of conditions and the following disclaimer in the documentation
27fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * and/or other materials
28fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * provided with the distribution.
29fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
30fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
38fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * POSSIBILITY OF SUCH DAMAGE.
41fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick */
42fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
437e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#ifdef CONFIG_PPC_64K_PAGES
447e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#include <linux/slab.h>
457e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#endif
464faf7757955239c1b259e7dab224d4638a99b456Joachim Fenkes
47263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher#include <linux/notifier.h>
48263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher#include <linux/memory.h>
49fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_classes.h"
50fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_iverbs.h"
51fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_mrmw.h"
52fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_tools.h"
53fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "hcp_if.h"
54fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
5550d40b8e53fab58b0141a75f7448eb28f9e21338Alexander Schmidt#define HCAD_VERSION "0029"
5639089e77741a53874eb8a29e4516bbafcc29298aJoachim Fenkes
57fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_LICENSE("Dual BSD/GPL");
58fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
59fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
6039089e77741a53874eb8a29e4516bbafcc29298aJoachim FenkesMODULE_VERSION(HCAD_VERSION);
61fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
6290ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool ehca_open_aqp1    = 0;
63e8e91f6b4dc1179a70b0d21241b769c0ebfaa129Roland Dreierstatic int ehca_hw_level      = 0;
6490ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool ehca_poll_all_eqs = 1;
65e8e91f6b4dc1179a70b0d21241b769c0ebfaa129Roland Dreier
66fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_debug_level   = 0;
6750d40b8e53fab58b0141a75f7448eb28f9e21338Alexander Schmidtint ehca_nr_ports      = -1;
6890ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellbool ehca_use_hp_mr    = 0;
69fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_port_act_time = 30;
70fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_static_rate   = -1;
7190ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellbool ehca_scaling_code = 0;
724faf7757955239c1b259e7dab224d4638a99b456Joachim Fenkesint ehca_lock_hcalls   = -1;
73d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscherint ehca_max_cq        = -1;
74d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscherint ehca_max_qp        = -1;
75fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
760455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkesmodule_param_named(open_aqp1,     ehca_open_aqp1,     bool, S_IRUGO);
770455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkesmodule_param_named(debug_level,   ehca_debug_level,   int,  S_IRUGO);
780455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkesmodule_param_named(hw_level,      ehca_hw_level,      int,  S_IRUGO);
790455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkesmodule_param_named(nr_ports,      ehca_nr_ports,      int,  S_IRUGO);
800455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkesmodule_param_named(use_hp_mr,     ehca_use_hp_mr,     bool, S_IRUGO);
810455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkesmodule_param_named(port_act_time, ehca_port_act_time, int,  S_IRUGO);
820455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkesmodule_param_named(poll_all_eqs,  ehca_poll_all_eqs,  bool, S_IRUGO);
830455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkesmodule_param_named(static_rate,   ehca_static_rate,   int,  S_IRUGO);
840455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkesmodule_param_named(scaling_code,  ehca_scaling_code,  bool, S_IRUGO);
8569116f279a9eaf4c540934269342d9149538fc79Rusty Russellmodule_param_named(lock_hcalls,   ehca_lock_hcalls,   bint, S_IRUGO);
86d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roschermodule_param_named(number_of_cqs, ehca_max_cq,        int,  S_IRUGO);
87d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roschermodule_param_named(number_of_qps, ehca_max_qp,        int,  S_IRUGO);
88fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
89fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(open_aqp1,
900455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkes		 "Open AQP1 on startup (default: no)");
91fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(debug_level,
924da27d6d5b92c8fe4b3a3e5bcf42606d9e4a6fc8Joachim Fenkes		 "Amount of debug output (0: none (default), 1: traces, "
934da27d6d5b92c8fe4b3a3e5bcf42606d9e4a6fc8Joachim Fenkes		 "2: some dumps, 3: lots)");
94fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(hw_level,
950455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkes		 "Hardware level (0: autosensing (default), "
960455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkes		 "0x10..0x14: eHCA, 0x20..0x23: eHCA2)");
97fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(nr_ports,
9850d40b8e53fab58b0141a75f7448eb28f9e21338Alexander Schmidt		 "number of connected ports (-1: autodetect (default), "
9950d40b8e53fab58b0141a75f7448eb28f9e21338Alexander Schmidt		 "1: port one only, 2: two ports)");
100fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(use_hp_mr,
1010455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkes		 "Use high performance MRs (default: no)");
102fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(port_act_time,
1030455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkes		 "Time to wait for port activation (default: 30 sec)");
104fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(poll_all_eqs,
1050455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkes		 "Poll all event queues periodically (default: yes)");
106fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(static_rate,
1070455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkes		 "Set permanent static rate (default: no static rate)");
1084fd3006032446be2b331dd482e34c6a9e644a5b8Hoang-Nam NguyenMODULE_PARM_DESC(scaling_code,
1090455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkes		 "Enable scaling code (default: no)");
1104faf7757955239c1b259e7dab224d4638a99b456Joachim FenkesMODULE_PARM_DESC(lock_hcalls,
1110455e36d81db76f5f4acb68a820da43adfa7ccecJoachim Fenkes		 "Serialize all hCalls made by the driver "
1124faf7757955239c1b259e7dab224d4638a99b456Joachim Fenkes		 "(default: autodetect)");
113d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan RoscherMODULE_PARM_DESC(number_of_cqs,
114d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher		"Max number of CQs which can be allocated "
115d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher		"(default: autodetect)");
116d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan RoscherMODULE_PARM_DESC(number_of_qps,
117d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher		"Max number of QPs which can be allocated "
118d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher		"(default: autodetect)");
119fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
12026ed687fdd541c2542b79dcd75fb2c82eb36f189Joachim FenkesDEFINE_RWLOCK(ehca_qp_idr_lock);
12126ed687fdd541c2542b79dcd75fb2c82eb36f189Joachim FenkesDEFINE_RWLOCK(ehca_cq_idr_lock);
122fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickDEFINE_IDR(ehca_qp_idr);
123fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickDEFINE_IDR(ehca_cq_idr);
124fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1259844b71baa60270110eabaa9589d3260443d1a71Joachim Fenkesstatic LIST_HEAD(shca_list); /* list of all registered ehcas */
1269420269428b3dc80c98e52beac60a3976fbef7d2Alexander SchmidtDEFINE_SPINLOCK(shca_list_lock);
127fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
128fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic struct timer_list poll_eqs_timer;
129fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1307e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#ifdef CONFIG_PPC_64K_PAGES
1312b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyenstatic struct kmem_cache *ctblk_cache;
1327e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen
133f2d9136133de257abbd97fec6f624d3a73d1e1fdHoang-Nam Nguyenvoid *ehca_alloc_fw_ctrlblock(gfp_t flags)
1347e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen{
135f2d9136133de257abbd97fec6f624d3a73d1e1fdHoang-Nam Nguyen	void *ret = kmem_cache_zalloc(ctblk_cache, flags);
1367e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	if (!ret)
1377e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		ehca_gen_err("Out of memory for ctblk");
1387e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	return ret;
1397e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen}
1407e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen
1417e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyenvoid ehca_free_fw_ctrlblock(void *ptr)
1427e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen{
1437e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	if (ptr)
1447e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		kmem_cache_free(ctblk_cache, ptr);
1457e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen
1467e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen}
1477e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#endif
1487e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen
14951d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyenint ehca2ib_return_code(u64 ehca_rc)
15051d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen{
15151d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen	switch (ehca_rc) {
15251d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen	case H_SUCCESS:
15351d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen		return 0;
15451d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen	case H_RESOURCE:             /* Resource in use */
15551d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen	case H_BUSY:
15651d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen		return -EBUSY;
15751d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen	case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */
15851d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen	case H_CONSTRAINED:          /* resource constraint */
15951d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen	case H_NO_MEM:
16051d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen		return -ENOMEM;
16151d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen	default:
16251d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen		return -EINVAL;
16351d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen	}
16451d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen}
16551d2bfbddb33dc59786a3a41f7eeb59e30fa561cHoang-Nam Nguyen
166fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic int ehca_create_slab_caches(void)
167fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
168fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
169fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
170fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_init_pd_cache();
171fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
172fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create PD SLAB cache.");
173fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return ret;
174fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
175fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
176fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_init_cq_cache();
177fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
178fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create CQ SLAB cache.");
179fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_slab_caches2;
180fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
181fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
182fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_init_qp_cache();
183fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
184fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create QP SLAB cache.");
185fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_slab_caches3;
186fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
187fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
188fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_init_av_cache();
189fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
190fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create AV SLAB cache.");
191fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_slab_caches4;
192fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
193fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
194fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_init_mrmw_cache();
195fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
196fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create MR&MW SLAB cache.");
197fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_slab_caches5;
198fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
199fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
200e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at	ret = ehca_init_small_qp_cache();
201e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at	if (ret) {
202e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at		ehca_gen_err("Cannot create small queue SLAB cache.");
203e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at		goto create_slab_caches6;
204e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at	}
205e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at
2067e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#ifdef CONFIG_PPC_64K_PAGES
2077e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	ctblk_cache = kmem_cache_create("ehca_cache_ctblk",
2087e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen					EHCA_PAGESIZE, H_CB_ALIGNMENT,
2097e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen					SLAB_HWCACHE_ALIGN,
21020c2df83d25c6a95affe6157a4c9cac4cf5ffaacPaul Mundt					NULL);
2117e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	if (!ctblk_cache) {
2127e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		ehca_gen_err("Cannot create ctblk SLAB cache.");
213e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at		ehca_cleanup_small_qp_cache();
214f29fa1cf340e21085672ccfeb6d66f292208567eWei Yongjun		ret = -ENOMEM;
215e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at		goto create_slab_caches6;
2167e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	}
2177e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#endif
218fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return 0;
219fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
220e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher atcreate_slab_caches6:
221e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at	ehca_cleanup_mrmw_cache();
222e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at
223fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_slab_caches5:
224fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_av_cache();
225fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
226fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_slab_caches4:
227fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_qp_cache();
228fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
229fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_slab_caches3:
230fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_cq_cache();
231fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
232fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_slab_caches2:
233fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_pd_cache();
234fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
235fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
236fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
237fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
238fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic void ehca_destroy_slab_caches(void)
239fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
240e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at	ehca_cleanup_small_qp_cache();
241fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_mrmw_cache();
242fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_av_cache();
243fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_qp_cache();
244fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_cq_cache();
245fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_pd_cache();
2467e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#ifdef CONFIG_PPC_64K_PAGES
2477e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	if (ctblk_cache)
2487e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		kmem_cache_destroy(ctblk_cache);
2497e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#endif
250fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
251fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
2522b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen#define EHCA_HCAAVER  EHCA_BMASK_IBM(32, 39)
2532b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen#define EHCA_REVID    EHCA_BMASK_IBM(40, 63)
254fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
25591f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkesstatic struct cap_descr {
25691f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	u64 mask;
25791f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	char *descr;
25891f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes} hca_cap_descr[] = {
25991f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_AH_PORT_NR_CHECK, "HCA_CAP_AH_PORT_NR_CHECK" },
26091f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_ATOMIC, "HCA_CAP_ATOMIC" },
26191f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_AUTO_PATH_MIG, "HCA_CAP_AUTO_PATH_MIG" },
26291f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_BAD_P_KEY_CTR, "HCA_CAP_BAD_P_KEY_CTR" },
26391f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_SQD_RTS_PORT_CHANGE, "HCA_CAP_SQD_RTS_PORT_CHANGE" },
26491f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_CUR_QP_STATE_MOD, "HCA_CAP_CUR_QP_STATE_MOD" },
26591f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_INIT_TYPE, "HCA_CAP_INIT_TYPE" },
26691f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_PORT_ACTIVE_EVENT, "HCA_CAP_PORT_ACTIVE_EVENT" },
26791f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_Q_KEY_VIOL_CTR, "HCA_CAP_Q_KEY_VIOL_CTR" },
26891f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_WQE_RESIZE, "HCA_CAP_WQE_RESIZE" },
26991f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_RAW_PACKET_MCAST, "HCA_CAP_RAW_PACKET_MCAST" },
27091f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_SHUTDOWN_PORT, "HCA_CAP_SHUTDOWN_PORT" },
27191f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_RC_LL_QP, "HCA_CAP_RC_LL_QP" },
27291f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_SRQ, "HCA_CAP_SRQ" },
27391f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_UD_LL_QP, "HCA_CAP_UD_LL_QP" },
27491f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_RESIZE_MR, "HCA_CAP_RESIZE_MR" },
27591f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	{ HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" },
2764faf7757955239c1b259e7dab224d4638a99b456Joachim Fenkes	{ HCA_CAP_H_ALLOC_RES_SYNC, "HCA_CAP_H_ALLOC_RES_SYNC" },
27791f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes};
27891f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes
279abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkesstatic int ehca_sense_attributes(struct ehca_shca *shca)
280fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
28191f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	int i, ret = 0;
282fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	u64 h_ret;
283fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct hipz_query_hca *rblock;
28491f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	struct hipz_query_port *port;
2854da27d6d5b92c8fe4b3a3e5bcf42606d9e4a6fc8Joachim Fenkes	const char *loc_code;
286fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
287abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkes	static const u32 pgsize_map[] = {
288abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkes		HCA_CAP_MR_PGSIZE_4K,  0x1000,
289abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkes		HCA_CAP_MR_PGSIZE_64K, 0x10000,
290abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkes		HCA_CAP_MR_PGSIZE_1M,  0x100000,
291abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkes		HCA_CAP_MR_PGSIZE_16M, 0x1000000,
292abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkes	};
293abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkes
2944da27d6d5b92c8fe4b3a3e5bcf42606d9e4a6fc8Joachim Fenkes	ehca_gen_dbg("Probing adapter %s...",
29561c7a080a5a061c976988fd4b844dfb468dda255Grant Likely		     shca->ofdev->dev.of_node->full_name);
29661c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	loc_code = of_get_property(shca->ofdev->dev.of_node, "ibm,loc-code",
29761c7a080a5a061c976988fd4b844dfb468dda255Grant Likely				   NULL);
2984da27d6d5b92c8fe4b3a3e5bcf42606d9e4a6fc8Joachim Fenkes	if (loc_code)
2994da27d6d5b92c8fe4b3a3e5bcf42606d9e4a6fc8Joachim Fenkes		ehca_gen_dbg(" ... location lode=%s", loc_code);
3004da27d6d5b92c8fe4b3a3e5bcf42606d9e4a6fc8Joachim Fenkes
301f2d9136133de257abbd97fec6f624d3a73d1e1fdHoang-Nam Nguyen	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
302fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!rblock) {
303fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot allocate rblock memory.");
304fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -ENOMEM;
305fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
306fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
307fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	h_ret = hipz_h_query_hca(shca->ipz_hca_handle, rblock);
308fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (h_ret != H_SUCCESS) {
3093750f60557b68776eb749859ad68af70d1a01ad0Stephen Rothwell		ehca_gen_err("Cannot query device properties. h_ret=%lli",
310fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			     h_ret);
311fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = -EPERM;
31291f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes		goto sense_attributes1;
313fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
314fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
315fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_nr_ports == 1)
316fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		shca->num_ports = 1;
317fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	else
318fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		shca->num_ports = (u8)rblock->num_ports;
319fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
320fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_gen_dbg(" ... found %x ports", rblock->num_ports);
321fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
322fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_hw_level == 0) {
323fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		u32 hcaaver;
324fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		u32 revid;
325fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
326fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		hcaaver = EHCA_BMASK_GET(EHCA_HCAAVER, rblock->hw_ver);
327fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		revid   = EHCA_BMASK_GET(EHCA_REVID, rblock->hw_ver);
328fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
329fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_dbg(" ... hardware version=%x:%x", hcaaver, revid);
330fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
331fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes		if (hcaaver == 1) {
332fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes			if (revid <= 3)
333fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes				shca->hw_level = 0x10 | (revid + 1);
334fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes			else
335fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes				shca->hw_level = 0x14;
336fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes		} else if (hcaaver == 2) {
337fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes			if (revid == 0)
338fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes				shca->hw_level = 0x21;
339fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes			else if (revid == 0x10)
340fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes				shca->hw_level = 0x22;
341fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes			else if (revid == 0x20 || revid == 0x21)
342fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes				shca->hw_level = 0x23;
343fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes		}
344fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes
345fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes		if (!shca->hw_level) {
34691f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes			ehca_gen_warn("unknown hardware version"
34791f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes				      " - assuming default level");
34891f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes			shca->hw_level = 0x22;
34991f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes		}
350fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes	} else
351fbb9318be4b6eba36482e1275729c5c3dfdf8156Joachim Fenkes		shca->hw_level = ehca_hw_level;
352fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_gen_dbg(" ... hardware level=%x", shca->hw_level);
353fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
35491f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	shca->hca_cap = rblock->hca_cap_indicators;
35591f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	ehca_gen_dbg(" ... HCA capabilities:");
35691f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	for (i = 0; i < ARRAY_SIZE(hca_cap_descr); i++)
35791f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes		if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
35891f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes			ehca_gen_dbg("   %s", hca_cap_descr[i].descr);
35991f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes
3604faf7757955239c1b259e7dab224d4638a99b456Joachim Fenkes	/* Autodetect hCall locking -- the "H_ALLOC_RESOURCE synced" flag is
3614faf7757955239c1b259e7dab224d4638a99b456Joachim Fenkes	 * a firmware property, so it's valid across all adapters
3624faf7757955239c1b259e7dab224d4638a99b456Joachim Fenkes	 */
3634faf7757955239c1b259e7dab224d4638a99b456Joachim Fenkes	if (ehca_lock_hcalls == -1)
36491fb0dd9cb71ab1a90ab1f48c34b935fdbca55b9Alexander Schmidt		ehca_lock_hcalls = !EHCA_BMASK_GET(HCA_CAP_H_ALLOC_RES_SYNC,
36591fb0dd9cb71ab1a90ab1f48c34b935fdbca55b9Alexander Schmidt					shca->hca_cap);
3664faf7757955239c1b259e7dab224d4638a99b456Joachim Fenkes
367abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkes	/* translate supported MR page sizes; always support 4K */
368abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkes	shca->hca_cap_mr_pgsize = EHCA_PAGESIZE;
369a7607c9b1112b498c3044c9e5bc68fdb4985f93eJoachim Fenkes	for (i = 0; i < ARRAY_SIZE(pgsize_map); i += 2)
370a7607c9b1112b498c3044c9e5bc68fdb4985f93eJoachim Fenkes		if (rblock->memory_page_size_supported & pgsize_map[i])
371a7607c9b1112b498c3044c9e5bc68fdb4985f93eJoachim Fenkes			shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
3725bb7d9290cd23a55906e4fe7a7fedecf29468c81Hoang-Nam Nguyen
373d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher	/* Set maximum number of CQs and QPs to calculate EQ size */
37419f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher	if (shca->max_num_qps == -1)
37519f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher		shca->max_num_qps = min_t(int, rblock->max_qp,
37619f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher					  EHCA_MAX_NUM_QUEUES);
37719f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher	else if (shca->max_num_qps < 1 || shca->max_num_qps > rblock->max_qp) {
37819f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher		ehca_gen_warn("The requested number of QPs is out of range "
37919f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher			      "(1 - %i) specified by HW. Value is set to %i",
38019f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher			      rblock->max_qp, rblock->max_qp);
38119f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher		shca->max_num_qps = rblock->max_qp;
382d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher	}
383d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher
38419f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher	if (shca->max_num_cqs == -1)
38519f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher		shca->max_num_cqs = min_t(int, rblock->max_cq,
38619f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher					  EHCA_MAX_NUM_QUEUES);
38719f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher	else if (shca->max_num_cqs < 1 || shca->max_num_cqs > rblock->max_cq) {
38819f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher		ehca_gen_warn("The requested number of CQs is out of range "
38919f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher			      "(1 - %i) specified by HW. Value is set to %i",
39019f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher			      rblock->max_cq, rblock->max_cq);
391d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher	}
392d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher
393abc39d3672d8af4bf6c943faf85fa8877caccf7eJoachim Fenkes	/* query max MTU from first port -- it's the same for all ports */
3942b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen	port = (struct hipz_query_port *)rblock;
39591f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
39691f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	if (h_ret != H_SUCCESS) {
3973750f60557b68776eb749859ad68af70d1a01ad0Stephen Rothwell		ehca_gen_err("Cannot query port properties. h_ret=%lli",
39891f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes			     h_ret);
39991f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes		ret = -EPERM;
40091f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes		goto sense_attributes1;
40191f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	}
40291f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes
40391f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes	shca->max_mtu = port->max_mtu;
40491f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkes
40591f13aa3fc22e357b494c5b8270e94543870928dJoachim Fenkessense_attributes1:
4067e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	ehca_free_fw_ctrlblock(rblock);
407fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
408fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
409fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
410fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic int init_node_guid(struct ehca_shca *shca)
411fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
412fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret = 0;
413fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct hipz_query_hca *rblock;
414fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
415f2d9136133de257abbd97fec6f624d3a73d1e1fdHoang-Nam Nguyen	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
416fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!rblock) {
417fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
418fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -ENOMEM;
419fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
420fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
421fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) {
422fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Can't query device properties");
423fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = -EINVAL;
424fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto init_node_guid1;
425fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
426fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
427fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64));
428fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
429fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickinit_node_guid1:
4307e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	ehca_free_fw_ctrlblock(rblock);
431fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
432fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
433fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
434e8e91f6b4dc1179a70b0d21241b769c0ebfaa129Roland Dreierstatic int ehca_init_device(struct ehca_shca *shca)
435fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
436fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
437fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
438fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = init_node_guid(shca);
439fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
440fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return ret;
441fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
442fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	strlcpy(shca->ib_device.name, "ehca%d", IB_DEVICE_NAME_MAX);
443fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.owner               = THIS_MODULE;
444fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
4455281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher	shca->ib_device.uverbs_abi_ver	    = 8;
446fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.uverbs_cmd_mask	    =
447fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_GET_CONTEXT)		|
448fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_QUERY_DEVICE)	|
449fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_QUERY_PORT)		|
450fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_ALLOC_PD)		|
451fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_DEALLOC_PD)		|
452fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_REG_MR)		|
453fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_DEREG_MR)		|
454fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL)	|
455fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_CREATE_CQ)		|
456fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_DESTROY_CQ)		|
457fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_CREATE_QP)		|
458fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_MODIFY_QP)		|
459fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_QUERY_QP)		|
460fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_DESTROY_QP)		|
461fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_ATTACH_MCAST)	|
462fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_DETACH_MCAST);
463fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
46407ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	shca->ib_device.node_type           = RDMA_NODE_IB_CA;
465fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.phys_port_cnt       = shca->num_ports;
466f4fd0b224d60044d2da5ca02f8f2b5150c1d8731Michael S. Tsirkin	shca->ib_device.num_comp_vectors    = 1;
4676b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes	shca->ib_device.dma_device          = &shca->ofdev->dev;
468fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_device        = ehca_query_device;
469fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_port          = ehca_query_port;
470fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_gid           = ehca_query_gid;
471fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_pkey          = ehca_query_pkey;
472fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* shca->in_device.modify_device    = ehca_modify_device    */
473fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.modify_port         = ehca_modify_port;
474fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.alloc_ucontext      = ehca_alloc_ucontext;
475fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dealloc_ucontext    = ehca_dealloc_ucontext;
476fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.alloc_pd            = ehca_alloc_pd;
477fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dealloc_pd          = ehca_dealloc_pd;
478fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.create_ah	    = ehca_create_ah;
479fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* shca->ib_device.modify_ah	    = ehca_modify_ah;	    */
480fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_ah	    = ehca_query_ah;
481fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.destroy_ah	    = ehca_destroy_ah;
482fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.create_qp	    = ehca_create_qp;
483fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.modify_qp	    = ehca_modify_qp;
484fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_qp	    = ehca_query_qp;
485fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.destroy_qp	    = ehca_destroy_qp;
486fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.post_send	    = ehca_post_send;
487fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.post_recv	    = ehca_post_recv;
488fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.create_cq	    = ehca_create_cq;
489fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.destroy_cq	    = ehca_destroy_cq;
490fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.resize_cq	    = ehca_resize_cq;
491fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.poll_cq		    = ehca_poll_cq;
492fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* shca->ib_device.peek_cq	    = ehca_peek_cq;	    */
493fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.req_notify_cq	    = ehca_req_notify_cq;
494fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* shca->ib_device.req_ncomp_notif  = ehca_req_ncomp_notif; */
495fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.get_dma_mr	    = ehca_get_dma_mr;
496fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.reg_phys_mr	    = ehca_reg_phys_mr;
497fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.reg_user_mr	    = ehca_reg_user_mr;
498fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_mr	    = ehca_query_mr;
499fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dereg_mr	    = ehca_dereg_mr;
500fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.rereg_phys_mr	    = ehca_rereg_phys_mr;
501fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.alloc_mw	    = ehca_alloc_mw;
502fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.bind_mw		    = ehca_bind_mw;
503fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dealloc_mw	    = ehca_dealloc_mw;
504fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.alloc_fmr	    = ehca_alloc_fmr;
505fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.map_phys_fmr	    = ehca_map_phys_fmr;
506fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.unmap_fmr	    = ehca_unmap_fmr;
507fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dealloc_fmr	    = ehca_dealloc_fmr;
508fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.attach_mcast	    = ehca_attach_mcast;
509fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.detach_mcast	    = ehca_detach_mcast;
5102b5e6b120e58d44cace68e6c7204b541a8b0b43fHoang-Nam Nguyen	shca->ib_device.process_mad	    = ehca_process_mad;
511fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.mmap		    = ehca_mmap;
5120cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering	shca->ib_device.dma_ops		    = &ehca_dma_mapping_ops;
513fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
514a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes	if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
515a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes		shca->ib_device.uverbs_cmd_mask |=
516a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes			(1ull << IB_USER_VERBS_CMD_CREATE_SRQ) |
517a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes			(1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) |
518a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes			(1ull << IB_USER_VERBS_CMD_QUERY_SRQ) |
519a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes			(1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
520a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes
521a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes		shca->ib_device.create_srq          = ehca_create_srq;
522a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes		shca->ib_device.modify_srq          = ehca_modify_srq;
523a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes		shca->ib_device.query_srq           = ehca_query_srq;
524a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes		shca->ib_device.destroy_srq         = ehca_destroy_srq;
525a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes		shca->ib_device.post_srq_recv       = ehca_post_srq_recv;
526a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes	}
527a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes
528fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
529fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
530fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
531fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic int ehca_create_aqp1(struct ehca_shca *shca, u32 port)
532fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
533fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ehca_sport *sport = &shca->sport[port - 1];
534fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ib_cq *ibcq;
535fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ib_qp *ibqp;
536fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ib_qp_init_attr qp_init_attr;
537fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
538fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
539fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (sport->ibcq_aqp1) {
540fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "AQP1 CQ is already created.");
541fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -EPERM;
542fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
543fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
5442b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen	ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void *)(-1), 10, 0);
545fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (IS_ERR(ibcq)) {
546fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create AQP1 CQ.");
547fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return PTR_ERR(ibcq);
548fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
549fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	sport->ibcq_aqp1 = ibcq;
550fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
551b8b50e353b85bc3c791dd2b99370ac300ebcd186Hoang-Nam Nguyen <hnguyen at	if (sport->ibqp_sqp[IB_QPT_GSI]) {
552fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "AQP1 QP is already created.");
553fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = -EPERM;
554fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_aqp1;
555fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
556fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
557fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	memset(&qp_init_attr, 0, sizeof(struct ib_qp_init_attr));
558fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.send_cq          = ibcq;
559fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.recv_cq          = ibcq;
560fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.sq_sig_type      = IB_SIGNAL_ALL_WR;
561fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.cap.max_send_wr  = 100;
562fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.cap.max_recv_wr  = 100;
563fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.cap.max_send_sge = 2;
564fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.cap.max_recv_sge = 1;
565fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.qp_type          = IB_QPT_GSI;
566fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.port_num         = port;
567fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.qp_context       = NULL;
568fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.event_handler    = NULL;
569fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.srq              = NULL;
570fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
571fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ibqp = ib_create_qp(&shca->pd->ib_pd, &qp_init_attr);
572fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (IS_ERR(ibqp)) {
573fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create AQP1 QP.");
574fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = PTR_ERR(ibqp);
575fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_aqp1;
576fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
577b8b50e353b85bc3c791dd2b99370ac300ebcd186Hoang-Nam Nguyen <hnguyen at	sport->ibqp_sqp[IB_QPT_GSI] = ibqp;
578fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
579fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return 0;
580fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
581fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_aqp1:
582fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ib_destroy_cq(sport->ibcq_aqp1);
583fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
584fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
585fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
586fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic int ehca_destroy_aqp1(struct ehca_sport *sport)
587fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
588fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
589fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
590b8b50e353b85bc3c791dd2b99370ac300ebcd186Hoang-Nam Nguyen <hnguyen at	ret = ib_destroy_qp(sport->ibqp_sqp[IB_QPT_GSI]);
591fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
592e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes		ehca_gen_err("Cannot destroy AQP1 QP. ret=%i", ret);
593fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return ret;
594fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
595fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
596fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ib_destroy_cq(sport->ibcq_aqp1);
597fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
598e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes		ehca_gen_err("Cannot destroy AQP1 CQ. ret=%i", ret);
599fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
600fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
601fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
602fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
603fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf)
604fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
6054da27d6d5b92c8fe4b3a3e5bcf42606d9e4a6fc8Joachim Fenkes	return snprintf(buf, PAGE_SIZE, "%d\n", ehca_debug_level);
606fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
607fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
608fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic ssize_t ehca_store_debug_level(struct device_driver *ddp,
609fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				      const char *buf, size_t count)
610fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
611fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int value = (*buf) - '0';
612fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (value >= 0 && value <= 9)
613fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_debug_level = value;
614fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return 1;
615fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
616fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
617e8e91f6b4dc1179a70b0d21241b769c0ebfaa129Roland Dreierstatic DRIVER_ATTR(debug_level, S_IRUSR | S_IWUSR,
618e8e91f6b4dc1179a70b0d21241b769c0ebfaa129Roland Dreier		   ehca_show_debug_level, ehca_store_debug_level);
619fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
620bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkesstatic struct attribute *ehca_drv_attrs[] = {
621bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&driver_attr_debug_level.attr,
622bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	NULL
623bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes};
624fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
625bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkesstatic struct attribute_group ehca_drv_attr_grp = {
626bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	.attrs = ehca_drv_attrs
627bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes};
628fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
629a4dbd6740df0872cdf0a86841f75beec8381964dDavid Brownellstatic const struct attribute_group *ehca_drv_attr_groups[] = {
63023b9c1ab5baf368a32b7242bf110ef1f48700d04Greg Kroah-Hartman	&ehca_drv_attr_grp,
63123b9c1ab5baf368a32b7242bf110ef1f48700d04Greg Kroah-Hartman	NULL,
63223b9c1ab5baf368a32b7242bf110ef1f48700d04Greg Kroah-Hartman};
63323b9c1ab5baf368a32b7242bf110ef1f48700d04Greg Kroah-Hartman
634fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#define EHCA_RESOURCE_ATTR(name)                                           \
635fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic ssize_t  ehca_show_##name(struct device *dev,                       \
636fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				 struct device_attribute *attr,            \
637fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				 char *buf)                                \
638fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{									   \
639fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ehca_shca *shca;						   \
640fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct hipz_query_hca *rblock;				           \
641fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int data;                                                          \
642fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
643f899c2ddd45f2515deb446e2b143e4a686a49aeeGreg Kroah-Hartman	shca = dev_get_drvdata(dev);					   \
644fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
645f2d9136133de257abbd97fec6f624d3a73d1e1fdHoang-Nam Nguyen	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);			   \
646fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!rblock) {						           \
647898eb71cb17644964c5895fb190e79e3d0c49679Joe Perches		dev_err(dev, "Can't allocate rblock memory.\n");           \
648fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return 0;						   \
649fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}								   \
650fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
651fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \
652898eb71cb17644964c5895fb190e79e3d0c49679Joe Perches		dev_err(dev, "Can't query device properties\n");           \
6537e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		ehca_free_fw_ctrlblock(rblock);			   	   \
654fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return 0;					   	   \
655fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}								   \
656fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
657fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	data = rblock->name;                                               \
6587e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	ehca_free_fw_ctrlblock(rblock);                                    \
659fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
660fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1))	   \
661fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return snprintf(buf, 256, "1\n");			   \
662fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	else								   \
663fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return snprintf(buf, 256, "%d\n", data);		   \
664fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
665fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}									   \
666fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic DEVICE_ATTR(name, S_IRUGO, ehca_show_##name, NULL);
667fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
668fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(num_ports);
669fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(hw_ver);
670fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_eq);
671fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(cur_eq);
672fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_cq);
673fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(cur_cq);
674fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_qp);
675fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(cur_qp);
676fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_mr);
677fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(cur_mr);
678fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_mw);
679fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(cur_mw);
680fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_pd);
681fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_ah);
682fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
683fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic ssize_t ehca_show_adapter_handle(struct device *dev,
684fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick					struct device_attribute *attr,
685fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick					char *buf)
686fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
687f899c2ddd45f2515deb446e2b143e4a686a49aeeGreg Kroah-Hartman	struct ehca_shca *shca = dev_get_drvdata(dev);
688fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
6893750f60557b68776eb749859ad68af70d1a01ad0Stephen Rothwell	return sprintf(buf, "%llx\n", shca->ipz_hca_handle.handle);
690fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
691fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
692fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL);
693fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
694bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkesstatic struct attribute *ehca_dev_attrs[] = {
695bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_adapter_handle.attr,
696bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_num_ports.attr,
697bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_hw_ver.attr,
698bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_max_eq.attr,
699bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_cur_eq.attr,
700bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_max_cq.attr,
701bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_cur_cq.attr,
702bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_max_qp.attr,
703bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_cur_qp.attr,
704bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_max_mr.attr,
705bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_cur_mr.attr,
706bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_max_mw.attr,
707bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_cur_mw.attr,
708bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_max_pd.attr,
709bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	&dev_attr_max_ah.attr,
710bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	NULL
711bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes};
712fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
713bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkesstatic struct attribute_group ehca_dev_attr_grp = {
714bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	.attrs = ehca_dev_attrs
715bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes};
716fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
717c45640e4a9f54f2f6f4bc51c2ba9644ffb3babdeRob Herringstatic int ehca_probe(struct platform_device *dev)
718fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
719fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ehca_shca *shca;
720a7edd0e676d51145ae634a2acf7a447e319200faStephen Rothwell	const u64 *handle;
721fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ib_pd *ibpd;
722d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher	int ret, i, eq_size;
72375c21ae9aa75b0452318d05f737ea838672137f5Joachim Fenkes	unsigned long flags;
724fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
72561c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	handle = of_get_property(dev->dev.of_node, "ibm,hca-handle", NULL);
726fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!handle) {
727fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot get eHCA handle for adapter: %s.",
72861c7a080a5a061c976988fd4b844dfb468dda255Grant Likely			     dev->dev.of_node->full_name);
729fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -ENODEV;
730fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
731fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
732fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!(*handle)) {
733fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Wrong eHCA handle for adapter: %s.",
73461c7a080a5a061c976988fd4b844dfb468dda255Grant Likely			     dev->dev.of_node->full_name);
735fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -ENODEV;
736fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
737fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
738fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca = (struct ehca_shca *)ib_alloc_device(sizeof(*shca));
739fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!shca) {
740fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot allocate shca memory.");
741fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -ENOMEM;
742fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
74319f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher
744c4ed790dfd4b2182c76e0fcd79d4aa85ab02eccfJoachim Fenkes	mutex_init(&shca->modify_mutex);
745d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher	atomic_set(&shca->num_cqs, 0);
746d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher	atomic_set(&shca->num_qps, 0);
74719f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher	shca->max_num_qps = ehca_max_qp;
74819f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher	shca->max_num_cqs = ehca_max_cq;
74919f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher
750bbdd267ef2796e96b461b8447b2026ce06e6ec4bHoang-Nam Nguyen	for (i = 0; i < ARRAY_SIZE(shca->sport); i++)
751bbdd267ef2796e96b461b8447b2026ce06e6ec4bHoang-Nam Nguyen		spin_lock_init(&shca->sport[i].mod_sqp_lock);
752fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
7536b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes	shca->ofdev = dev;
754fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ipz_hca_handle.handle = *handle;
755f899c2ddd45f2515deb446e2b143e4a686a49aeeGreg Kroah-Hartman	dev_set_drvdata(&dev->dev, shca);
756fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
757fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_sense_attributes(shca);
758fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret < 0) {
759fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot sense eHCA attributes.");
760fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto probe1;
761fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
762fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
7630f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen	ret = ehca_init_device(shca);
764fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
7650f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen		ehca_gen_err("Cannot init ehca  device struct");
766fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto probe1;
767fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
768fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
76919f4282149147b4a3e8c670373dc73ddd5d5faccStefan Roscher	eq_size = 2 * shca->max_num_cqs + 4 * shca->max_num_qps;
770fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* create event queues */
771d227fa7288adebe5ba37fa8e4a589c977d4e4a34Stefan Roscher	ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size);
772fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
773fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create EQ.");
7740f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen		goto probe1;
775fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
776fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
777fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513);
778fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
779fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create NEQ.");
780fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto probe3;
781fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
782fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
783fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* create internal protection domain */
7842b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen	ibpd = ehca_alloc_pd(&shca->ib_device, (void *)(-1), NULL);
785fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (IS_ERR(ibpd)) {
786fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create internal PD.");
787fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = PTR_ERR(ibpd);
788fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto probe4;
789fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
790fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
791fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->pd = container_of(ibpd, struct ehca_pd, ib_pd);
792fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->pd->ib_pd.device = &shca->ib_device;
793fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
794fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* create internal max MR */
795fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_reg_internal_maxmr(shca, shca->pd, &shca->maxmr);
796fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
797fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
798e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes		ehca_err(&shca->ib_device, "Cannot create internal MR ret=%i",
799fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 ret);
800fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto probe5;
801fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
802fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
8039a6edb60ec10d86b1025a0cdad68fd89f1ddaf02Ralph Campbell	ret = ib_register_device(&shca->ib_device, NULL);
8040f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen	if (ret) {
8050f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen		ehca_err(&shca->ib_device,
806e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes			 "ib_register_device() failed ret=%i", ret);
8070f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen		goto probe6;
8080f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen	}
8090f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen
810fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* create AQP1 for port 1 */
811fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_open_aqp1 == 1) {
812fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		shca->sport[0].port_state = IB_PORT_DOWN;
813fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = ehca_create_aqp1(shca, 1);
814fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		if (ret) {
815fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			ehca_err(&shca->ib_device,
816fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				 "Cannot create AQP1 for port 1.");
8170f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen			goto probe7;
818fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		}
819fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
820fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
821fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* create AQP1 for port 2 */
822fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if ((ehca_open_aqp1 == 1) && (shca->num_ports == 2)) {
823fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		shca->sport[1].port_state = IB_PORT_DOWN;
824fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = ehca_create_aqp1(shca, 2);
825fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		if (ret) {
826fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			ehca_err(&shca->ib_device,
827fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				 "Cannot create AQP1 for port 2.");
8280f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen			goto probe8;
829fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		}
830fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
831fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
8326b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes	ret = sysfs_create_group(&dev->dev.kobj, &ehca_dev_attr_grp);
833bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes	if (ret) /* only complain; we can live without attributes */
834bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes		ehca_err(&shca->ib_device,
835bba9b6013e604fadb298191c058149acf1cdfcedJoachim Fenkes			 "Cannot create device attributes  ret=%d", ret);
836fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
83775c21ae9aa75b0452318d05f737ea838672137f5Joachim Fenkes	spin_lock_irqsave(&shca_list_lock, flags);
838fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	list_add(&shca->shca_list, &shca_list);
83975c21ae9aa75b0452318d05f737ea838672137f5Joachim Fenkes	spin_unlock_irqrestore(&shca_list_lock, flags);
840fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
841fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return 0;
842fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
8430f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyenprobe8:
844fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_destroy_aqp1(&shca->sport[0]);
845fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
846fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
847e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes			 "Cannot destroy AQP1 for port 1. ret=%i", ret);
848fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
8490f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyenprobe7:
8500f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen	ib_unregister_device(&shca->ib_device);
8510f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen
852fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickprobe6:
853fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_dereg_internal_maxmr(shca);
854fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
855fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
856fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy internal MR. ret=%x", ret);
857fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
858fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickprobe5:
859fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_dealloc_pd(&shca->pd->ib_pd);
860fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
861fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
862fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy internal PD. ret=%x", ret);
863fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
864fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickprobe4:
865fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_destroy_eq(shca, &shca->neq);
866fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
867fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
868fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy NEQ. ret=%x", ret);
869fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
870fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickprobe3:
871fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_destroy_eq(shca, &shca->eq);
872fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
873fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
874fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy EQ. ret=%x", ret);
875fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
876fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickprobe1:
877fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ib_dealloc_device(&shca->ib_device);
878fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
879fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return -EINVAL;
880fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
881fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
8821e6d9abea73128cff1160624a8986570c48a095bGreg Kroah-Hartmanstatic int ehca_remove(struct platform_device *dev)
883fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
884f899c2ddd45f2515deb446e2b143e4a686a49aeeGreg Kroah-Hartman	struct ehca_shca *shca = dev_get_drvdata(&dev->dev);
88575c21ae9aa75b0452318d05f737ea838672137f5Joachim Fenkes	unsigned long flags;
886fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
887fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
8886b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes	sysfs_remove_group(&dev->dev.kobj, &ehca_dev_attr_grp);
889fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
890fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_open_aqp1 == 1) {
891fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		int i;
892fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		for (i = 0; i < shca->num_ports; i++) {
893fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			ret = ehca_destroy_aqp1(&shca->sport[i]);
894fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			if (ret)
895fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				ehca_err(&shca->ib_device,
896fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick					 "Cannot destroy AQP1 for port %x "
897e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes					 "ret=%i", ret, i);
898fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		}
899fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
900fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
901fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ib_unregister_device(&shca->ib_device);
902fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
903fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_dereg_internal_maxmr(shca);
904fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
905fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
906e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes			 "Cannot destroy internal MR. ret=%i", ret);
907fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
908fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_dealloc_pd(&shca->pd->ib_pd);
909fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
910fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
911e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes			 "Cannot destroy internal PD. ret=%i", ret);
912fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
913fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_destroy_eq(shca, &shca->eq);
914fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
915e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes		ehca_err(&shca->ib_device, "Cannot destroy EQ. ret=%i", ret);
916fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
917fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_destroy_eq(shca, &shca->neq);
918fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
919e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes		ehca_err(&shca->ib_device, "Canot destroy NEQ. ret=%i", ret);
920fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
921fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ib_dealloc_device(&shca->ib_device);
922fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
92375c21ae9aa75b0452318d05f737ea838672137f5Joachim Fenkes	spin_lock_irqsave(&shca_list_lock, flags);
924fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	list_del(&shca->shca_list);
92575c21ae9aa75b0452318d05f737ea838672137f5Joachim Fenkes	spin_unlock_irqrestore(&shca_list_lock, flags);
926fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
927fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
928fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
929fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
930fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic struct of_device_id ehca_device_table[] =
931fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
932fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	{
933fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		.name       = "lhca",
934fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		.compatible = "IBM,lhca",
935fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	},
936fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	{},
937fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick};
938038919f29682b00ea95506e959210fc72d1aaf64Joachim FenkesMODULE_DEVICE_TABLE(of, ehca_device_table);
939fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
940c45640e4a9f54f2f6f4bc51c2ba9644ffb3babdeRob Herringstatic struct platform_driver ehca_driver = {
9416b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes	.probe       = ehca_probe,
9426b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes	.remove      = ehca_remove,
9434018294b53d1dae026880e45f174c1cc63b5d435Grant Likely	.driver = {
9444018294b53d1dae026880e45f174c1cc63b5d435Grant Likely		.name = "ehca",
9454018294b53d1dae026880e45f174c1cc63b5d435Grant Likely		.owner = THIS_MODULE,
94623b9c1ab5baf368a32b7242bf110ef1f48700d04Greg Kroah-Hartman		.groups = ehca_drv_attr_groups,
9474018294b53d1dae026880e45f174c1cc63b5d435Grant Likely		.of_match_table = ehca_device_table,
94823b9c1ab5baf368a32b7242bf110ef1f48700d04Greg Kroah-Hartman	},
949fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick};
950fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
951fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickvoid ehca_poll_eqs(unsigned long data)
952fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
953fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ehca_shca *shca;
954fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
955fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_lock(&shca_list_lock);
956fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	list_for_each_entry(shca, &shca_list, shca_list) {
95778d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen		if (shca->eq.is_initialized) {
95878d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			/* call deadman proc only if eq ptr does not change */
95978d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			struct ehca_eq *eq = &shca->eq;
96078d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			int max = 3;
96178d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			volatile u64 q_ofs, q_ofs2;
9627ddccb234ce1039f89387e0cec9c29dccf6e3476Stephen Rothwell			unsigned long flags;
96378d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			spin_lock_irqsave(&eq->spinlock, flags);
96478d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			q_ofs = eq->ipz_queue.current_q_offset;
96578d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			spin_unlock_irqrestore(&eq->spinlock, flags);
96678d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			do {
96778d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen				spin_lock_irqsave(&eq->spinlock, flags);
96878d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen				q_ofs2 = eq->ipz_queue.current_q_offset;
96978d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen				spin_unlock_irqrestore(&eq->spinlock, flags);
97078d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen				max--;
97178d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			} while (q_ofs == q_ofs2 && max > 0);
97278d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			if (q_ofs == q_ofs2)
97378d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen				ehca_process_eq(shca, 0);
97478d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen		}
975fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
9761a7d2dce4169ed42310926a5675fffd0986caa26Anton Blanchard	mod_timer(&poll_eqs_timer, round_jiffies(jiffies + HZ));
977fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_unlock(&shca_list_lock);
978fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
979fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
980263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscherstatic int ehca_mem_notifier(struct notifier_block *nb,
981263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher			     unsigned long action, void *data)
982263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher{
983263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	static unsigned long ehca_dmem_warn_time;
98475c21ae9aa75b0452318d05f737ea838672137f5Joachim Fenkes	unsigned long flags;
985263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher
986263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	switch (action) {
987263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	case MEM_CANCEL_OFFLINE:
988263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	case MEM_CANCEL_ONLINE:
989263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	case MEM_ONLINE:
990263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	case MEM_OFFLINE:
991263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher		return NOTIFY_OK;
992263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	case MEM_GOING_ONLINE:
993263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	case MEM_GOING_OFFLINE:
994263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher		/* only ok if no hca is attached to the lpar */
99575c21ae9aa75b0452318d05f737ea838672137f5Joachim Fenkes		spin_lock_irqsave(&shca_list_lock, flags);
996263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher		if (list_empty(&shca_list)) {
99775c21ae9aa75b0452318d05f737ea838672137f5Joachim Fenkes			spin_unlock_irqrestore(&shca_list_lock, flags);
998263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher			return NOTIFY_OK;
999263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher		} else {
100075c21ae9aa75b0452318d05f737ea838672137f5Joachim Fenkes			spin_unlock_irqrestore(&shca_list_lock, flags);
1001263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher			if (printk_timed_ratelimit(&ehca_dmem_warn_time,
1002263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher						   30 * 1000))
1003263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher				ehca_gen_err("DMEM operations are not allowed"
10046b1f9d647e848060d34c3db408413989f1e460baJoachim Fenkes					     "in conjunction with eHCA");
1005263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher			return NOTIFY_BAD;
1006263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher		}
1007263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	}
1008263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	return NOTIFY_OK;
1009263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher}
1010263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher
1011263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscherstatic struct notifier_block ehca_mem_nb = {
1012263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	.notifier_call = ehca_mem_notifier,
1013263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher};
1014263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher
1015e8e91f6b4dc1179a70b0d21241b769c0ebfaa129Roland Dreierstatic int __init ehca_module_init(void)
1016fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
1017fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
1018fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1019fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	printk(KERN_INFO "eHCA Infiniband Device Driver "
102039089e77741a53874eb8a29e4516bbafcc29298aJoachim Fenkes	       "(Version " HCAD_VERSION ")\n");
1021fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
10222b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen	ret = ehca_create_comp_pool();
10232b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen	if (ret) {
1024fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create comp pool.");
1025fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return ret;
1026fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
1027fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
10282b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen	ret = ehca_create_slab_caches();
10292b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen	if (ret) {
1030fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create SLAB caches");
1031fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = -ENOMEM;
1032fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto module_init1;
1033fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
1034fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
10350cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering	ret = ehca_create_busmap();
10360cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering	if (ret) {
10370cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering		ehca_gen_err("Cannot create busmap.");
10380cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering		goto module_init2;
10390cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering	}
10400cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering
10412b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen	ret = ibmebus_register_driver(&ehca_driver);
10422b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen	if (ret) {
1043fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot register eHCA device driver");
1044fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = -EINVAL;
10450cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering		goto module_init3;
1046fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
1047fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1048263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	ret = register_memory_notifier(&ehca_mem_nb);
1049263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	if (ret) {
1050263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher		ehca_gen_err("Failed registering memory add/remove notifier");
10510cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering		goto module_init4;
1052263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	}
1053263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher
1054fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_poll_all_eqs != 1) {
1055fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("WARNING!!!");
1056fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("It is possible to lose interrupts.");
1057fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	} else {
1058fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		init_timer(&poll_eqs_timer);
1059fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		poll_eqs_timer.function = ehca_poll_eqs;
1060fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		poll_eqs_timer.expires = jiffies + HZ;
1061fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		add_timer(&poll_eqs_timer);
1062fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
1063fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1064fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return 0;
1065fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
10660cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Heringmodule_init4:
1067263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	ibmebus_unregister_driver(&ehca_driver);
1068263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher
10690cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Heringmodule_init3:
10700cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering	ehca_destroy_busmap();
10710cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering
1072fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_init2:
1073fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_destroy_slab_caches();
1074fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1075fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_init1:
1076fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_destroy_comp_pool();
1077fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
1078fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick};
1079fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1080e8e91f6b4dc1179a70b0d21241b769c0ebfaa129Roland Dreierstatic void __exit ehca_module_exit(void)
1081fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
1082fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_poll_all_eqs == 1)
1083fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		del_timer_sync(&poll_eqs_timer);
1084fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1085fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ibmebus_unregister_driver(&ehca_driver);
1086fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1087263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher	unregister_memory_notifier(&ehca_mem_nb);
1088263c24a2bbbaca75805ed231e8346d86410af9d0Stefan Roscher
10890cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering	ehca_destroy_busmap();
10900cf89dcdbc53f2b43e4ce7419b6ff47f4309c2ebHannes Hering
1091fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_destroy_slab_caches();
1092fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1093fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_destroy_comp_pool();
1094fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1095fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	idr_destroy(&ehca_cq_idr);
1096fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	idr_destroy(&ehca_qp_idr);
1097fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick};
1098fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1099fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_init(ehca_module_init);
1100fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_exit(ehca_module_exit);
1101