Merge mulgrave-w:git/scsi-misc-2.6
[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 "hcp_if.h"
44
45 int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
46 {
47         int ret = 0;
48         struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
49                                               ib_device);
50         struct hipz_query_hca *rblock;
51
52         rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
53         if (!rblock) {
54                 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
55                 return -ENOMEM;
56         }
57
58         if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) {
59                 ehca_err(&shca->ib_device, "Can't query device properties");
60                 ret = -EINVAL;
61                 goto query_device1;
62         }
63
64         memset(props, 0, sizeof(struct ib_device_attr));
65         props->fw_ver          = rblock->hw_ver;
66         props->max_mr_size     = rblock->max_mr_size;
67         props->vendor_id       = rblock->vendor_id >> 8;
68         props->vendor_part_id  = rblock->vendor_part_id >> 16;
69         props->hw_ver          = rblock->hw_ver;
70         props->max_qp          = min_t(int, rblock->max_qp, INT_MAX);
71         props->max_qp_wr       = min_t(int, rblock->max_wqes_wq, INT_MAX);
72         props->max_sge         = min_t(int, rblock->max_sge, INT_MAX);
73         props->max_sge_rd      = min_t(int, rblock->max_sge_rd, INT_MAX);
74         props->max_cq          = min_t(int, rblock->max_cq, INT_MAX);
75         props->max_cqe         = min_t(int, rblock->max_cqe, INT_MAX);
76         props->max_mr          = min_t(int, rblock->max_mr, INT_MAX);
77         props->max_mw          = min_t(int, rblock->max_mw, INT_MAX);
78         props->max_pd          = min_t(int, rblock->max_pd, INT_MAX);
79         props->max_ah          = min_t(int, rblock->max_ah, INT_MAX);
80         props->max_fmr         = min_t(int, rblock->max_mr, INT_MAX);
81         props->max_srq         = 0;
82         props->max_srq_wr      = 0;
83         props->max_srq_sge     = 0;
84         props->max_pkeys       = 16;
85         props->local_ca_ack_delay
86                 = rblock->local_ca_ack_delay;
87         props->max_raw_ipv6_qp
88                 = min_t(int, rblock->max_raw_ipv6_qp, INT_MAX);
89         props->max_raw_ethy_qp
90                 = min_t(int, rblock->max_raw_ethy_qp, INT_MAX);
91         props->max_mcast_grp
92                 = min_t(int, rblock->max_mcast_grp, INT_MAX);
93         props->max_mcast_qp_attach
94                 = min_t(int, rblock->max_mcast_qp_attach, INT_MAX);
95         props->max_total_mcast_qp_attach
96                 = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX);
97
98 query_device1:
99         kfree(rblock);
100
101         return ret;
102 }
103
104 int ehca_query_port(struct ib_device *ibdev,
105                     u8 port, struct ib_port_attr *props)
106 {
107         int ret = 0;
108         struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
109                                               ib_device);
110         struct hipz_query_port *rblock;
111
112         rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
113         if (!rblock) {
114                 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
115                 return -ENOMEM;
116         }
117
118         if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
119                 ehca_err(&shca->ib_device, "Can't query port properties");
120                 ret = -EINVAL;
121                 goto query_port1;
122         }
123
124         memset(props, 0, sizeof(struct ib_port_attr));
125         props->state = rblock->state;
126
127         switch (rblock->max_mtu) {
128         case 0x1:
129                 props->active_mtu = props->max_mtu = IB_MTU_256;
130                 break;
131         case 0x2:
132                 props->active_mtu = props->max_mtu = IB_MTU_512;
133                 break;
134         case 0x3:
135                 props->active_mtu = props->max_mtu = IB_MTU_1024;
136                 break;
137         case 0x4:
138                 props->active_mtu = props->max_mtu = IB_MTU_2048;
139                 break;
140         case 0x5:
141                 props->active_mtu = props->max_mtu = IB_MTU_4096;
142                 break;
143         default:
144                 ehca_err(&shca->ib_device, "Unknown MTU size: %x.",
145                          rblock->max_mtu);
146                 break;
147         }
148
149         props->gid_tbl_len     = rblock->gid_tbl_len;
150         props->max_msg_sz      = rblock->max_msg_sz;
151         props->bad_pkey_cntr   = rblock->bad_pkey_cntr;
152         props->qkey_viol_cntr  = rblock->qkey_viol_cntr;
153         props->pkey_tbl_len    = rblock->pkey_tbl_len;
154         props->lid             = rblock->lid;
155         props->sm_lid          = rblock->sm_lid;
156         props->lmc             = rblock->lmc;
157         props->sm_sl           = rblock->sm_sl;
158         props->subnet_timeout  = rblock->subnet_timeout;
159         props->init_type_reply = rblock->init_type_reply;
160
161         props->active_width    = IB_WIDTH_12X;
162         props->active_speed    = 0x1;
163
164 query_port1:
165         kfree(rblock);
166
167         return ret;
168 }
169
170 int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
171 {
172         int ret = 0;
173         struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device);
174         struct hipz_query_port *rblock;
175
176         if (index > 16) {
177                 ehca_err(&shca->ib_device, "Invalid index: %x.", index);
178                 return -EINVAL;
179         }
180
181         rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
182         if (!rblock) {
183                 ehca_err(&shca->ib_device,  "Can't allocate rblock memory.");
184                 return -ENOMEM;
185         }
186
187         if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
188                 ehca_err(&shca->ib_device, "Can't query port properties");
189                 ret = -EINVAL;
190                 goto query_pkey1;
191         }
192
193         memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16));
194
195 query_pkey1:
196         kfree(rblock);
197
198         return ret;
199 }
200
201 int ehca_query_gid(struct ib_device *ibdev, u8 port,
202                    int index, union ib_gid *gid)
203 {
204         int ret = 0;
205         struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
206                                               ib_device);
207         struct hipz_query_port *rblock;
208
209         if (index > 255) {
210                 ehca_err(&shca->ib_device, "Invalid index: %x.", index);
211                 return -EINVAL;
212         }
213
214         rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
215         if (!rblock) {
216                 ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
217                 return -ENOMEM;
218         }
219
220         if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
221                 ehca_err(&shca->ib_device, "Can't query port properties");
222                 ret = -EINVAL;
223                 goto query_gid1;
224         }
225
226         memcpy(&gid->raw[0], &rblock->gid_prefix, sizeof(u64));
227         memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64));
228
229 query_gid1:
230         kfree(rblock);
231
232         return ret;
233 }
234
235 int ehca_modify_port(struct ib_device *ibdev,
236                      u8 port, int port_modify_mask,
237                      struct ib_port_modify *props)
238 {
239         /* Not implemented yet */
240         return -EFAULT;
241 }