Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[pandora-kernel.git] / drivers / infiniband / hw / ehca / ehca_hca.c
1 /*
2  *  IBM eServer eHCA Infiniband device driver for Linux on POWER
3  *
4  *  HCA query functions
5  *
6  *  Authors: Heiko J Schick <schickhj@de.ibm.com>
7  *           Christoph Raisch <raisch@de.ibm.com>
8  *
9  *  Copyright (c) 2005 IBM Corporation
10  *
11  *  All rights reserved.
12  *
13  *  This source code is distributed under a dual license of GPL v2.0 and OpenIB
14  *  BSD.
15  *
16  * OpenIB BSD License
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are met:
20  *
21  * Redistributions of source code must retain the above copyright notice, this
22  * list of conditions and the following disclaimer.
23  *
24  * Redistributions in binary form must reproduce the above copyright notice,
25  * this list of conditions and the following disclaimer in the documentation
26  * and/or other materials
27  * provided with the distribution.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39  * POSSIBILITY OF SUCH DAMAGE.
40  */
41
42 #include "ehca_tools.h"
43 #include "ehca_iverbs.h"
44 #include "hcp_if.h"
45
46 int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
47 {
48         int ret = 0;
49         struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
50                                               ib_device);
51         struct hipz_query_hca *rblock;
52
53         rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
54         if (!rblock) {
55                 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
56                 return -ENOMEM;
57         }
58
59         if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) {
60                 ehca_err(&shca->ib_device, "Can't query device properties");
61                 ret = -EINVAL;
62                 goto query_device1;
63         }
64
65         memset(props, 0, sizeof(struct ib_device_attr));
66         props->fw_ver          = rblock->hw_ver;
67         props->max_mr_size     = rblock->max_mr_size;
68         props->vendor_id       = rblock->vendor_id >> 8;
69         props->vendor_part_id  = rblock->vendor_part_id >> 16;
70         props->hw_ver          = rblock->hw_ver;
71         props->max_qp          = min_t(int, rblock->max_qp, INT_MAX);
72         props->max_qp_wr       = min_t(int, rblock->max_wqes_wq, INT_MAX);
73         props->max_sge         = min_t(int, rblock->max_sge, INT_MAX);
74         props->max_sge_rd      = min_t(int, rblock->max_sge_rd, INT_MAX);
75         props->max_cq          = min_t(int, rblock->max_cq, INT_MAX);
76         props->max_cqe         = min_t(int, rblock->max_cqe, INT_MAX);
77         props->max_mr          = min_t(int, rblock->max_mr, INT_MAX);
78         props->max_mw          = min_t(int, rblock->max_mw, INT_MAX);
79         props->max_pd          = min_t(int, rblock->max_pd, INT_MAX);
80         props->max_ah          = min_t(int, rblock->max_ah, INT_MAX);
81         props->max_fmr         = min_t(int, rblock->max_mr, INT_MAX);
82         props->max_srq         = 0;
83         props->max_srq_wr      = 0;
84         props->max_srq_sge     = 0;
85         props->max_pkeys       = 16;
86         props->local_ca_ack_delay
87                 = rblock->local_ca_ack_delay;
88         props->max_raw_ipv6_qp
89                 = min_t(int, rblock->max_raw_ipv6_qp, INT_MAX);
90         props->max_raw_ethy_qp
91                 = min_t(int, rblock->max_raw_ethy_qp, INT_MAX);
92         props->max_mcast_grp
93                 = min_t(int, rblock->max_mcast_grp, INT_MAX);
94         props->max_mcast_qp_attach
95                 = min_t(int, rblock->max_mcast_qp_attach, INT_MAX);
96         props->max_total_mcast_qp_attach
97                 = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX);
98
99 query_device1:
100         ehca_free_fw_ctrlblock(rblock);
101
102         return ret;
103 }
104
105 int ehca_query_port(struct ib_device *ibdev,
106                     u8 port, struct ib_port_attr *props)
107 {
108         int ret = 0;
109         struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
110                                               ib_device);
111         struct hipz_query_port *rblock;
112
113         rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
114         if (!rblock) {
115                 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
116                 return -ENOMEM;
117         }
118
119         if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
120                 ehca_err(&shca->ib_device, "Can't query port properties");
121                 ret = -EINVAL;
122                 goto query_port1;
123         }
124
125         memset(props, 0, sizeof(struct ib_port_attr));
126         props->state = rblock->state;
127
128         switch (rblock->max_mtu) {
129         case 0x1:
130                 props->active_mtu = props->max_mtu = IB_MTU_256;
131                 break;
132         case 0x2:
133                 props->active_mtu = props->max_mtu = IB_MTU_512;
134                 break;
135         case 0x3:
136                 props->active_mtu = props->max_mtu = IB_MTU_1024;
137                 break;
138         case 0x4:
139                 props->active_mtu = props->max_mtu = IB_MTU_2048;
140                 break;
141         case 0x5:
142                 props->active_mtu = props->max_mtu = IB_MTU_4096;
143                 break;
144         default:
145                 ehca_err(&shca->ib_device, "Unknown MTU size: %x.",
146                          rblock->max_mtu);
147                 break;
148         }
149
150         props->gid_tbl_len     = rblock->gid_tbl_len;
151         props->max_msg_sz      = rblock->max_msg_sz;
152         props->bad_pkey_cntr   = rblock->bad_pkey_cntr;
153         props->qkey_viol_cntr  = rblock->qkey_viol_cntr;
154         props->pkey_tbl_len    = rblock->pkey_tbl_len;
155         props->lid             = rblock->lid;
156         props->sm_lid          = rblock->sm_lid;
157         props->lmc             = rblock->lmc;
158         props->sm_sl           = rblock->sm_sl;
159         props->subnet_timeout  = rblock->subnet_timeout;
160         props->init_type_reply = rblock->init_type_reply;
161
162         props->active_width    = IB_WIDTH_12X;
163         props->active_speed    = 0x1;
164
165 query_port1:
166         ehca_free_fw_ctrlblock(rblock);
167
168         return ret;
169 }
170
171 int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
172 {
173         int ret = 0;
174         struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device);
175         struct hipz_query_port *rblock;
176
177         if (index > 16) {
178                 ehca_err(&shca->ib_device, "Invalid index: %x.", index);
179                 return -EINVAL;
180         }
181
182         rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
183         if (!rblock) {
184                 ehca_err(&shca->ib_device,  "Can't allocate rblock memory.");
185                 return -ENOMEM;
186         }
187
188         if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
189                 ehca_err(&shca->ib_device, "Can't query port properties");
190                 ret = -EINVAL;
191                 goto query_pkey1;
192         }
193
194         memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16));
195
196 query_pkey1:
197         ehca_free_fw_ctrlblock(rblock);
198
199         return ret;
200 }
201
202 int ehca_query_gid(struct ib_device *ibdev, u8 port,
203                    int index, union ib_gid *gid)
204 {
205         int ret = 0;
206         struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
207                                               ib_device);
208         struct hipz_query_port *rblock;
209
210         if (index > 255) {
211                 ehca_err(&shca->ib_device, "Invalid index: %x.", index);
212                 return -EINVAL;
213         }
214
215         rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
216         if (!rblock) {
217                 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
218                 return -ENOMEM;
219         }
220
221         if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
222                 ehca_err(&shca->ib_device, "Can't query port properties");
223                 ret = -EINVAL;
224                 goto query_gid1;
225         }
226
227         memcpy(&gid->raw[0], &rblock->gid_prefix, sizeof(u64));
228         memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64));
229
230 query_gid1:
231         ehca_free_fw_ctrlblock(rblock);
232
233         return ret;
234 }
235
236 int ehca_modify_port(struct ib_device *ibdev,
237                      u8 port, int port_modify_mask,
238                      struct ib_port_modify *props)
239 {
240         /* Not implemented yet */
241         return -EFAULT;
242 }