diff options
author | Bryan O'Sullivan <bos@pathscale.com> | 2006-03-29 18:23:28 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-03-31 16:14:19 -0500 |
commit | 097709fea03140b567bde8369f3ffafe33dfc1c6 (patch) | |
tree | 98ef94e0abcf13798c6f416ba7a5318ab4b47d7d /drivers/infiniband/hw/ipath | |
parent | dc741bbd4f47080c623d243546dd4cb5ff6c9564 (diff) |
IB/ipath: chip initialisation code, and diag support
ipath_init_chip.c sets up an InfiniPath device for use.
ipath_diag.c permits userspace diagnostic tools to read and write a
chip's registers. It is different in purpose from the mmap interfaces
to the /sys/bus/pci resource files.
Signed-off-by: Bryan O'Sullivan <bos@pathscale.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_diag.c | 379 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_init_chip.c | 951 |
2 files changed, 1330 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c new file mode 100644 index 00000000000..cd533cf951c --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_diag.c | |||
@@ -0,0 +1,379 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
3 | * | ||
4 | * This software is available to you under a choice of one of two | ||
5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
6 | * General Public License (GPL) Version 2, available from the file | ||
7 | * COPYING in the main directory of this source tree, or the | ||
8 | * OpenIB.org BSD license below: | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or | ||
11 | * without modification, are permitted provided that the following | ||
12 | * conditions are met: | ||
13 | * | ||
14 | * - Redistributions of source code must retain the above | ||
15 | * copyright notice, this list of conditions and the following | ||
16 | * disclaimer. | ||
17 | * | ||
18 | * - Redistributions in binary form must reproduce the above | ||
19 | * copyright notice, this list of conditions and the following | ||
20 | * disclaimer in the documentation and/or other materials | ||
21 | * provided with the distribution. | ||
22 | * | ||
23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
30 | * SOFTWARE. | ||
31 | */ | ||
32 | |||
33 | /* | ||
34 | * This file contains support for diagnostic functions. It is accessed by | ||
35 | * opening the ipath_diag device, normally minor number 129. Diagnostic use | ||
36 | * of the InfiniPath chip may render the chip or board unusable until the | ||
37 | * driver is unloaded, or in some cases, until the system is rebooted. | ||
38 | * | ||
39 | * Accesses to the chip through this interface are not similar to going | ||
40 | * through the /sys/bus/pci resource mmap interface. | ||
41 | */ | ||
42 | |||
43 | #include <linux/pci.h> | ||
44 | #include <asm/uaccess.h> | ||
45 | |||
46 | #include "ipath_common.h" | ||
47 | #include "ipath_kernel.h" | ||
48 | #include "ips_common.h" | ||
49 | #include "ipath_layer.h" | ||
50 | |||
51 | int ipath_diag_inuse; | ||
52 | static int diag_set_link; | ||
53 | |||
54 | static int ipath_diag_open(struct inode *in, struct file *fp); | ||
55 | static int ipath_diag_release(struct inode *in, struct file *fp); | ||
56 | static ssize_t ipath_diag_read(struct file *fp, char __user *data, | ||
57 | size_t count, loff_t *off); | ||
58 | static ssize_t ipath_diag_write(struct file *fp, const char __user *data, | ||
59 | size_t count, loff_t *off); | ||
60 | |||
61 | static struct file_operations diag_file_ops = { | ||
62 | .owner = THIS_MODULE, | ||
63 | .write = ipath_diag_write, | ||
64 | .read = ipath_diag_read, | ||
65 | .open = ipath_diag_open, | ||
66 | .release = ipath_diag_release | ||
67 | }; | ||
68 | |||
69 | static struct cdev *diag_cdev; | ||
70 | static struct class_device *diag_class_dev; | ||
71 | |||
72 | int ipath_diag_init(void) | ||
73 | { | ||
74 | return ipath_cdev_init(IPATH_DIAG_MINOR, "ipath_diag", | ||
75 | &diag_file_ops, &diag_cdev, &diag_class_dev); | ||
76 | } | ||
77 | |||
78 | void ipath_diag_cleanup(void) | ||
79 | { | ||
80 | ipath_cdev_cleanup(&diag_cdev, &diag_class_dev); | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * ipath_read_umem64 - read a 64-bit quantity from the chip into user space | ||
85 | * @dd: the infinipath device | ||
86 | * @uaddr: the location to store the data in user memory | ||
87 | * @caddr: the source chip address (full pointer, not offset) | ||
88 | * @count: number of bytes to copy (multiple of 32 bits) | ||
89 | * | ||
90 | * This function also localizes all chip memory accesses. | ||
91 | * The copy should be written such that we read full cacheline packets | ||
92 | * from the chip. This is usually used for a single qword | ||
93 | * | ||
94 | * NOTE: This assumes the chip address is 64-bit aligned. | ||
95 | */ | ||
96 | static int ipath_read_umem64(struct ipath_devdata *dd, void __user *uaddr, | ||
97 | const void __iomem *caddr, size_t count) | ||
98 | { | ||
99 | const u64 __iomem *reg_addr = caddr; | ||
100 | const u64 __iomem *reg_end = reg_addr + (count / sizeof(u64)); | ||
101 | int ret; | ||
102 | |||
103 | /* not very efficient, but it works for now */ | ||
104 | if (reg_addr < dd->ipath_kregbase || | ||
105 | reg_end > dd->ipath_kregend) { | ||
106 | ret = -EINVAL; | ||
107 | goto bail; | ||
108 | } | ||
109 | while (reg_addr < reg_end) { | ||
110 | u64 data = readq(reg_addr); | ||
111 | if (copy_to_user(uaddr, &data, sizeof(u64))) { | ||
112 | ret = -EFAULT; | ||
113 | goto bail; | ||
114 | } | ||
115 | reg_addr++; | ||
116 | uaddr++; | ||
117 | } | ||
118 | ret = 0; | ||
119 | bail: | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * ipath_write_umem64 - write a 64-bit quantity to the chip from user space | ||
125 | * @dd: the infinipath device | ||
126 | * @caddr: the destination chip address (full pointer, not offset) | ||
127 | * @uaddr: the source of the data in user memory | ||
128 | * @count: the number of bytes to copy (multiple of 32 bits) | ||
129 | * | ||
130 | * This is usually used for a single qword | ||
131 | * NOTE: This assumes the chip address is 64-bit aligned. | ||
132 | */ | ||
133 | |||
134 | static int ipath_write_umem64(struct ipath_devdata *dd, void __iomem *caddr, | ||
135 | const void __user *uaddr, size_t count) | ||
136 | { | ||
137 | u64 __iomem *reg_addr = caddr; | ||
138 | const u64 __iomem *reg_end = reg_addr + (count / sizeof(u64)); | ||
139 | int ret; | ||
140 | |||
141 | /* not very efficient, but it works for now */ | ||
142 | if (reg_addr < dd->ipath_kregbase || | ||
143 | reg_end > dd->ipath_kregend) { | ||
144 | ret = -EINVAL; | ||
145 | goto bail; | ||
146 | } | ||
147 | while (reg_addr < reg_end) { | ||
148 | u64 data; | ||
149 | if (copy_from_user(&data, uaddr, sizeof(data))) { | ||
150 | ret = -EFAULT; | ||
151 | goto bail; | ||
152 | } | ||
153 | writeq(data, reg_addr); | ||
154 | |||
155 | reg_addr++; | ||
156 | uaddr++; | ||
157 | } | ||
158 | ret = 0; | ||
159 | bail: | ||
160 | return ret; | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * ipath_read_umem32 - read a 32-bit quantity from the chip into user space | ||
165 | * @dd: the infinipath device | ||
166 | * @uaddr: the location to store the data in user memory | ||
167 | * @caddr: the source chip address (full pointer, not offset) | ||
168 | * @count: number of bytes to copy | ||
169 | * | ||
170 | * read 32 bit values, not 64 bit; for memories that only | ||
171 | * support 32 bit reads; usually a single dword. | ||
172 | */ | ||
173 | static int ipath_read_umem32(struct ipath_devdata *dd, void __user *uaddr, | ||
174 | const void __iomem *caddr, size_t count) | ||
175 | { | ||
176 | const u32 __iomem *reg_addr = caddr; | ||
177 | const u32 __iomem *reg_end = reg_addr + (count / sizeof(u32)); | ||
178 | int ret; | ||
179 | |||
180 | if (reg_addr < (u32 __iomem *) dd->ipath_kregbase || | ||
181 | reg_end > (u32 __iomem *) dd->ipath_kregend) { | ||
182 | ret = -EINVAL; | ||
183 | goto bail; | ||
184 | } | ||
185 | /* not very efficient, but it works for now */ | ||
186 | while (reg_addr < reg_end) { | ||
187 | u32 data = readl(reg_addr); | ||
188 | if (copy_to_user(uaddr, &data, sizeof(data))) { | ||
189 | ret = -EFAULT; | ||
190 | goto bail; | ||
191 | } | ||
192 | |||
193 | reg_addr++; | ||
194 | uaddr++; | ||
195 | } | ||
196 | ret = 0; | ||
197 | bail: | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | /** | ||
202 | * ipath_write_umem32 - write a 32-bit quantity to the chip from user space | ||
203 | * @dd: the infinipath device | ||
204 | * @caddr: the destination chip address (full pointer, not offset) | ||
205 | * @uaddr: the source of the data in user memory | ||
206 | * @count: number of bytes to copy | ||
207 | * | ||
208 | * write 32 bit values, not 64 bit; for memories that only | ||
209 | * support 32 bit write; usually a single dword. | ||
210 | */ | ||
211 | |||
212 | static int ipath_write_umem32(struct ipath_devdata *dd, void __iomem *caddr, | ||
213 | const void __user *uaddr, size_t count) | ||
214 | { | ||
215 | u32 __iomem *reg_addr = caddr; | ||
216 | const u32 __iomem *reg_end = reg_addr + (count / sizeof(u32)); | ||
217 | int ret; | ||
218 | |||
219 | if (reg_addr < (u32 __iomem *) dd->ipath_kregbase || | ||
220 | reg_end > (u32 __iomem *) dd->ipath_kregend) { | ||
221 | ret = -EINVAL; | ||
222 | goto bail; | ||
223 | } | ||
224 | while (reg_addr < reg_end) { | ||
225 | u32 data; | ||
226 | if (copy_from_user(&data, uaddr, sizeof(data))) { | ||
227 | ret = -EFAULT; | ||
228 | goto bail; | ||
229 | } | ||
230 | writel(data, reg_addr); | ||
231 | |||
232 | reg_addr++; | ||
233 | uaddr++; | ||
234 | } | ||
235 | ret = 0; | ||
236 | bail: | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | static int ipath_diag_open(struct inode *in, struct file *fp) | ||
241 | { | ||
242 | struct ipath_devdata *dd; | ||
243 | int unit = 0; /* XXX this is bogus */ | ||
244 | unsigned long flags; | ||
245 | int ret; | ||
246 | |||
247 | dd = ipath_lookup(unit); | ||
248 | |||
249 | mutex_lock(&ipath_mutex); | ||
250 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
251 | |||
252 | if (ipath_diag_inuse) { | ||
253 | ret = -EBUSY; | ||
254 | goto bail; | ||
255 | } | ||
256 | |||
257 | list_for_each_entry(dd, &ipath_dev_list, ipath_list) { | ||
258 | /* | ||
259 | * we need at least one infinipath device to be present | ||
260 | * (don't use INITTED, because we want to be able to open | ||
261 | * even if device is in freeze mode, which cleared INITTED). | ||
262 | * There is a small amount of risk to this, which is why we | ||
263 | * also verify kregbase is set. | ||
264 | */ | ||
265 | |||
266 | if (!(dd->ipath_flags & IPATH_PRESENT) || | ||
267 | !dd->ipath_kregbase) | ||
268 | continue; | ||
269 | |||
270 | ipath_diag_inuse = 1; | ||
271 | diag_set_link = 0; | ||
272 | ret = 0; | ||
273 | goto bail; | ||
274 | } | ||
275 | |||
276 | ret = -ENODEV; | ||
277 | |||
278 | bail: | ||
279 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
280 | mutex_unlock(&ipath_mutex); | ||
281 | |||
282 | /* Only expose a way to reset the device if we | ||
283 | make it into diag mode. */ | ||
284 | if (ret == 0) | ||
285 | ipath_expose_reset(&dd->pcidev->dev); | ||
286 | |||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | static int ipath_diag_release(struct inode *i, struct file *f) | ||
291 | { | ||
292 | mutex_lock(&ipath_mutex); | ||
293 | ipath_diag_inuse = 0; | ||
294 | mutex_unlock(&ipath_mutex); | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static ssize_t ipath_diag_read(struct file *fp, char __user *data, | ||
299 | size_t count, loff_t *off) | ||
300 | { | ||
301 | int unit = 0; /* XXX provide for reads on other units some day */ | ||
302 | struct ipath_devdata *dd; | ||
303 | void __iomem *kreg_base; | ||
304 | ssize_t ret; | ||
305 | |||
306 | dd = ipath_lookup(unit); | ||
307 | if (!dd) { | ||
308 | ret = -ENODEV; | ||
309 | goto bail; | ||
310 | } | ||
311 | |||
312 | kreg_base = dd->ipath_kregbase; | ||
313 | |||
314 | if (count == 0) | ||
315 | ret = 0; | ||
316 | else if ((count % 4) || (*off % 4)) | ||
317 | /* address or length is not 32-bit aligned, hence invalid */ | ||
318 | ret = -EINVAL; | ||
319 | else if ((count % 8) || (*off % 8)) | ||
320 | /* address or length not 64-bit aligned; do 32-bit reads */ | ||
321 | ret = ipath_read_umem32(dd, data, kreg_base + *off, count); | ||
322 | else | ||
323 | ret = ipath_read_umem64(dd, data, kreg_base + *off, count); | ||
324 | |||
325 | if (ret >= 0) { | ||
326 | *off += count; | ||
327 | ret = count; | ||
328 | } | ||
329 | |||
330 | bail: | ||
331 | return ret; | ||
332 | } | ||
333 | |||
334 | static ssize_t ipath_diag_write(struct file *fp, const char __user *data, | ||
335 | size_t count, loff_t *off) | ||
336 | { | ||
337 | int unit = 0; /* XXX this is bogus */ | ||
338 | struct ipath_devdata *dd; | ||
339 | void __iomem *kreg_base; | ||
340 | ssize_t ret; | ||
341 | |||
342 | dd = ipath_lookup(unit); | ||
343 | if (!dd) { | ||
344 | ret = -ENODEV; | ||
345 | goto bail; | ||
346 | } | ||
347 | kreg_base = dd->ipath_kregbase; | ||
348 | |||
349 | if (count == 0) | ||
350 | ret = 0; | ||
351 | else if ((count % 4) || (*off % 4)) | ||
352 | /* address or length is not 32-bit aligned, hence invalid */ | ||
353 | ret = -EINVAL; | ||
354 | else if ((count % 8) || (*off % 8)) | ||
355 | /* address or length not 64-bit aligned; do 32-bit writes */ | ||
356 | ret = ipath_write_umem32(dd, kreg_base + *off, data, count); | ||
357 | else | ||
358 | ret = ipath_write_umem64(dd, kreg_base + *off, data, count); | ||
359 | |||
360 | if (ret >= 0) { | ||
361 | *off += count; | ||
362 | ret = count; | ||
363 | } | ||
364 | |||
365 | bail: | ||
366 | return ret; | ||
367 | } | ||
368 | |||
369 | void ipath_diag_bringup_link(struct ipath_devdata *dd) | ||
370 | { | ||
371 | if (diag_set_link || (dd->ipath_flags & IPATH_LINKACTIVE)) | ||
372 | return; | ||
373 | |||
374 | diag_set_link = 1; | ||
375 | ipath_cdbg(VERBOSE, "Trying to set to set link active for " | ||
376 | "diag pkt\n"); | ||
377 | ipath_layer_set_linkstate(dd, IPATH_IB_LINKARM); | ||
378 | ipath_layer_set_linkstate(dd, IPATH_IB_LINKACTIVE); | ||
379 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c new file mode 100644 index 00000000000..2823ff9c0c6 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c | |||
@@ -0,0 +1,951 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
3 | * | ||
4 | * This software is available to you under a choice of one of two | ||
5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
6 | * General Public License (GPL) Version 2, available from the file | ||
7 | * COPYING in the main directory of this source tree, or the | ||
8 | * OpenIB.org BSD license below: | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or | ||
11 | * without modification, are permitted provided that the following | ||
12 | * conditions are met: | ||
13 | * | ||
14 | * - Redistributions of source code must retain the above | ||
15 | * copyright notice, this list of conditions and the following | ||
16 | * disclaimer. | ||
17 | * | ||
18 | * - Redistributions in binary form must reproduce the above | ||
19 | * copyright notice, this list of conditions and the following | ||
20 | * disclaimer in the documentation and/or other materials | ||
21 | * provided with the distribution. | ||
22 | * | ||
23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
30 | * SOFTWARE. | ||
31 | */ | ||
32 | |||
33 | #include <linux/pci.h> | ||
34 | #include <linux/netdevice.h> | ||
35 | #include <linux/vmalloc.h> | ||
36 | |||
37 | #include "ipath_kernel.h" | ||
38 | #include "ips_common.h" | ||
39 | |||
40 | /* | ||
41 | * min buffers we want to have per port, after driver | ||
42 | */ | ||
43 | #define IPATH_MIN_USER_PORT_BUFCNT 8 | ||
44 | |||
45 | /* | ||
46 | * Number of ports we are configured to use (to allow for more pio | ||
47 | * buffers per port, etc.) Zero means use chip value. | ||
48 | */ | ||
49 | static ushort ipath_cfgports; | ||
50 | |||
51 | module_param_named(cfgports, ipath_cfgports, ushort, S_IRUGO); | ||
52 | MODULE_PARM_DESC(cfgports, "Set max number of ports to use"); | ||
53 | |||
54 | /* | ||
55 | * Number of buffers reserved for driver (layered drivers and SMA | ||
56 | * send). Reserved at end of buffer list. | ||
57 | */ | ||
58 | static ushort ipath_kpiobufs = 32; | ||
59 | |||
60 | static int ipath_set_kpiobufs(const char *val, struct kernel_param *kp); | ||
61 | |||
62 | module_param_call(kpiobufs, ipath_set_kpiobufs, param_get_uint, | ||
63 | &ipath_kpiobufs, S_IWUSR | S_IRUGO); | ||
64 | MODULE_PARM_DESC(kpiobufs, "Set number of PIO buffers for driver"); | ||
65 | |||
66 | /** | ||
67 | * create_port0_egr - allocate the eager TID buffers | ||
68 | * @dd: the infinipath device | ||
69 | * | ||
70 | * This code is now quite different for user and kernel, because | ||
71 | * the kernel uses skb's, for the accelerated network performance. | ||
72 | * This is the kernel (port0) version. | ||
73 | * | ||
74 | * Allocate the eager TID buffers and program them into infinipath. | ||
75 | * We use the network layer alloc_skb() allocator to allocate the | ||
76 | * memory, and either use the buffers as is for things like SMA | ||
77 | * packets, or pass the buffers up to the ipath layered driver and | ||
78 | * thence the network layer, replacing them as we do so (see | ||
79 | * ipath_rcv_layer()). | ||
80 | */ | ||
81 | static int create_port0_egr(struct ipath_devdata *dd) | ||
82 | { | ||
83 | unsigned e, egrcnt; | ||
84 | struct sk_buff **skbs; | ||
85 | int ret; | ||
86 | |||
87 | egrcnt = dd->ipath_rcvegrcnt; | ||
88 | |||
89 | skbs = vmalloc(sizeof(*dd->ipath_port0_skbs) * egrcnt); | ||
90 | if (skbs == NULL) { | ||
91 | ipath_dev_err(dd, "allocation error for eager TID " | ||
92 | "skb array\n"); | ||
93 | ret = -ENOMEM; | ||
94 | goto bail; | ||
95 | } | ||
96 | for (e = 0; e < egrcnt; e++) { | ||
97 | /* | ||
98 | * This is a bit tricky in that we allocate extra | ||
99 | * space for 2 bytes of the 14 byte ethernet header. | ||
100 | * These two bytes are passed in the ipath header so | ||
101 | * the rest of the data is word aligned. We allocate | ||
102 | * 4 bytes so that the data buffer stays word aligned. | ||
103 | * See ipath_kreceive() for more details. | ||
104 | */ | ||
105 | skbs[e] = ipath_alloc_skb(dd, GFP_KERNEL); | ||
106 | if (!skbs[e]) { | ||
107 | ipath_dev_err(dd, "SKB allocation error for " | ||
108 | "eager TID %u\n", e); | ||
109 | while (e != 0) | ||
110 | dev_kfree_skb(skbs[--e]); | ||
111 | ret = -ENOMEM; | ||
112 | goto bail; | ||
113 | } | ||
114 | } | ||
115 | /* | ||
116 | * After loop above, so we can test non-NULL to see if ready | ||
117 | * to use at receive, etc. | ||
118 | */ | ||
119 | dd->ipath_port0_skbs = skbs; | ||
120 | |||
121 | for (e = 0; e < egrcnt; e++) { | ||
122 | unsigned long phys = | ||
123 | virt_to_phys(dd->ipath_port0_skbs[e]->data); | ||
124 | dd->ipath_f_put_tid(dd, e + (u64 __iomem *) | ||
125 | ((char __iomem *) dd->ipath_kregbase + | ||
126 | dd->ipath_rcvegrbase), 0, phys); | ||
127 | } | ||
128 | |||
129 | ret = 0; | ||
130 | |||
131 | bail: | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | static int bringup_link(struct ipath_devdata *dd) | ||
136 | { | ||
137 | u64 val, ibc; | ||
138 | int ret = 0; | ||
139 | |||
140 | /* hold IBC in reset */ | ||
141 | dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; | ||
142 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
143 | dd->ipath_control); | ||
144 | |||
145 | /* | ||
146 | * Note that prior to try 14 or 15 of IB, the credit scaling | ||
147 | * wasn't working, because it was swapped for writes with the | ||
148 | * 1 bit default linkstate field | ||
149 | */ | ||
150 | |||
151 | /* ignore pbc and align word */ | ||
152 | val = dd->ipath_piosize2k - 2 * sizeof(u32); | ||
153 | /* | ||
154 | * for ICRC, which we only send in diag test pkt mode, and we | ||
155 | * don't need to worry about that for mtu | ||
156 | */ | ||
157 | val += 1; | ||
158 | /* | ||
159 | * Set the IBC maxpktlength to the size of our pio buffers the | ||
160 | * maxpktlength is in words. This is *not* the IB data MTU. | ||
161 | */ | ||
162 | ibc = (val / sizeof(u32)) << INFINIPATH_IBCC_MAXPKTLEN_SHIFT; | ||
163 | /* in KB */ | ||
164 | ibc |= 0x5ULL << INFINIPATH_IBCC_FLOWCTRLWATERMARK_SHIFT; | ||
165 | /* | ||
166 | * How often flowctrl sent. More or less in usecs; balance against | ||
167 | * watermark value, so that in theory senders always get a flow | ||
168 | * control update in time to not let the IB link go idle. | ||
169 | */ | ||
170 | ibc |= 0x3ULL << INFINIPATH_IBCC_FLOWCTRLPERIOD_SHIFT; | ||
171 | /* max error tolerance */ | ||
172 | ibc |= 0xfULL << INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT; | ||
173 | /* use "real" buffer space for */ | ||
174 | ibc |= 4ULL << INFINIPATH_IBCC_CREDITSCALE_SHIFT; | ||
175 | /* IB credit flow control. */ | ||
176 | ibc |= 0xfULL << INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT; | ||
177 | /* initially come up waiting for TS1, without sending anything. */ | ||
178 | dd->ipath_ibcctrl = ibc; | ||
179 | /* | ||
180 | * Want to start out with both LINKCMD and LINKINITCMD in NOP | ||
181 | * (0 and 0). Don't put linkinitcmd in ipath_ibcctrl, want that | ||
182 | * to stay a NOP | ||
183 | */ | ||
184 | ibc |= INFINIPATH_IBCC_LINKINITCMD_DISABLE << | ||
185 | INFINIPATH_IBCC_LINKINITCMD_SHIFT; | ||
186 | ipath_cdbg(VERBOSE, "Writing 0x%llx to ibcctrl\n", | ||
187 | (unsigned long long) ibc); | ||
188 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, ibc); | ||
189 | |||
190 | // be sure chip saw it | ||
191 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
192 | |||
193 | ret = dd->ipath_f_bringup_serdes(dd); | ||
194 | |||
195 | if (ret) | ||
196 | dev_info(&dd->pcidev->dev, "Could not initialize SerDes, " | ||
197 | "not usable\n"); | ||
198 | else { | ||
199 | /* enable IBC */ | ||
200 | dd->ipath_control |= INFINIPATH_C_LINKENABLE; | ||
201 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
202 | dd->ipath_control); | ||
203 | } | ||
204 | |||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static int init_chip_first(struct ipath_devdata *dd, | ||
209 | struct ipath_portdata **pdp) | ||
210 | { | ||
211 | struct ipath_portdata *pd = NULL; | ||
212 | int ret = 0; | ||
213 | u64 val; | ||
214 | |||
215 | /* | ||
216 | * skip cfgports stuff because we are not allocating memory, | ||
217 | * and we don't want problems if the portcnt changed due to | ||
218 | * cfgports. We do still check and report a difference, if | ||
219 | * not same (should be impossible). | ||
220 | */ | ||
221 | dd->ipath_portcnt = | ||
222 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); | ||
223 | if (!ipath_cfgports) | ||
224 | dd->ipath_cfgports = dd->ipath_portcnt; | ||
225 | else if (ipath_cfgports <= dd->ipath_portcnt) { | ||
226 | dd->ipath_cfgports = ipath_cfgports; | ||
227 | ipath_dbg("Configured to use %u ports out of %u in chip\n", | ||
228 | dd->ipath_cfgports, dd->ipath_portcnt); | ||
229 | } else { | ||
230 | dd->ipath_cfgports = dd->ipath_portcnt; | ||
231 | ipath_dbg("Tried to configured to use %u ports; chip " | ||
232 | "only supports %u\n", ipath_cfgports, | ||
233 | dd->ipath_portcnt); | ||
234 | } | ||
235 | dd->ipath_pd = kzalloc(sizeof(*dd->ipath_pd) * dd->ipath_cfgports, | ||
236 | GFP_KERNEL); | ||
237 | |||
238 | if (!dd->ipath_pd) { | ||
239 | ipath_dev_err(dd, "Unable to allocate portdata array, " | ||
240 | "failing\n"); | ||
241 | ret = -ENOMEM; | ||
242 | goto done; | ||
243 | } | ||
244 | |||
245 | dd->ipath_lastegrheads = kzalloc(sizeof(*dd->ipath_lastegrheads) | ||
246 | * dd->ipath_cfgports, | ||
247 | GFP_KERNEL); | ||
248 | dd->ipath_lastrcvhdrqtails = | ||
249 | kzalloc(sizeof(*dd->ipath_lastrcvhdrqtails) | ||
250 | * dd->ipath_cfgports, GFP_KERNEL); | ||
251 | |||
252 | if (!dd->ipath_lastegrheads || !dd->ipath_lastrcvhdrqtails) { | ||
253 | ipath_dev_err(dd, "Unable to allocate head arrays, " | ||
254 | "failing\n"); | ||
255 | ret = -ENOMEM; | ||
256 | goto done; | ||
257 | } | ||
258 | |||
259 | dd->ipath_pd[0] = kzalloc(sizeof(*pd), GFP_KERNEL); | ||
260 | |||
261 | if (!dd->ipath_pd[0]) { | ||
262 | ipath_dev_err(dd, "Unable to allocate portdata for port " | ||
263 | "0, failing\n"); | ||
264 | ret = -ENOMEM; | ||
265 | goto done; | ||
266 | } | ||
267 | pd = dd->ipath_pd[0]; | ||
268 | pd->port_dd = dd; | ||
269 | pd->port_port = 0; | ||
270 | pd->port_cnt = 1; | ||
271 | /* The port 0 pkey table is used by the layer interface. */ | ||
272 | pd->port_pkeys[0] = IPS_DEFAULT_P_KEY; | ||
273 | dd->ipath_rcvtidcnt = | ||
274 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidcnt); | ||
275 | dd->ipath_rcvtidbase = | ||
276 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidbase); | ||
277 | dd->ipath_rcvegrcnt = | ||
278 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrcnt); | ||
279 | dd->ipath_rcvegrbase = | ||
280 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrbase); | ||
281 | dd->ipath_palign = | ||
282 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_pagealign); | ||
283 | dd->ipath_piobufbase = | ||
284 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpiobufbase); | ||
285 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpiosize); | ||
286 | dd->ipath_piosize2k = val & ~0U; | ||
287 | dd->ipath_piosize4k = val >> 32; | ||
288 | dd->ipath_ibmtu = 4096; /* default to largest legal MTU */ | ||
289 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpiobufcnt); | ||
290 | dd->ipath_piobcnt2k = val & ~0U; | ||
291 | dd->ipath_piobcnt4k = val >> 32; | ||
292 | dd->ipath_pio2kbase = | ||
293 | (u32 __iomem *) (((char __iomem *) dd->ipath_kregbase) + | ||
294 | (dd->ipath_piobufbase & 0xffffffff)); | ||
295 | if (dd->ipath_piobcnt4k) { | ||
296 | dd->ipath_pio4kbase = (u32 __iomem *) | ||
297 | (((char __iomem *) dd->ipath_kregbase) + | ||
298 | (dd->ipath_piobufbase >> 32)); | ||
299 | /* | ||
300 | * 4K buffers take 2 pages; we use roundup just to be | ||
301 | * paranoid; we calculate it once here, rather than on | ||
302 | * ever buf allocate | ||
303 | */ | ||
304 | dd->ipath_4kalign = ALIGN(dd->ipath_piosize4k, | ||
305 | dd->ipath_palign); | ||
306 | ipath_dbg("%u 2k(%x) piobufs @ %p, %u 4k(%x) @ %p " | ||
307 | "(%x aligned)\n", | ||
308 | dd->ipath_piobcnt2k, dd->ipath_piosize2k, | ||
309 | dd->ipath_pio2kbase, dd->ipath_piobcnt4k, | ||
310 | dd->ipath_piosize4k, dd->ipath_pio4kbase, | ||
311 | dd->ipath_4kalign); | ||
312 | } | ||
313 | else ipath_dbg("%u 2k piobufs @ %p\n", | ||
314 | dd->ipath_piobcnt2k, dd->ipath_pio2kbase); | ||
315 | |||
316 | spin_lock_init(&dd->ipath_tid_lock); | ||
317 | |||
318 | done: | ||
319 | *pdp = pd; | ||
320 | return ret; | ||
321 | } | ||
322 | |||
323 | /** | ||
324 | * init_chip_reset - re-initialize after a reset, or enable | ||
325 | * @dd: the infinipath device | ||
326 | * @pdp: output for port data | ||
327 | * | ||
328 | * sanity check at least some of the values after reset, and | ||
329 | * ensure no receive or transmit (explictly, in case reset | ||
330 | * failed | ||
331 | */ | ||
332 | static int init_chip_reset(struct ipath_devdata *dd, | ||
333 | struct ipath_portdata **pdp) | ||
334 | { | ||
335 | struct ipath_portdata *pd; | ||
336 | u32 rtmp; | ||
337 | |||
338 | *pdp = pd = dd->ipath_pd[0]; | ||
339 | /* ensure chip does no sends or receives while we re-initialize */ | ||
340 | dd->ipath_control = dd->ipath_sendctrl = dd->ipath_rcvctrl = 0U; | ||
341 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, 0); | ||
342 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 0); | ||
343 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0); | ||
344 | |||
345 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); | ||
346 | if (dd->ipath_portcnt != rtmp) | ||
347 | dev_info(&dd->pcidev->dev, "portcnt was %u before " | ||
348 | "reset, now %u, using original\n", | ||
349 | dd->ipath_portcnt, rtmp); | ||
350 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidcnt); | ||
351 | if (rtmp != dd->ipath_rcvtidcnt) | ||
352 | dev_info(&dd->pcidev->dev, "tidcnt was %u before " | ||
353 | "reset, now %u, using original\n", | ||
354 | dd->ipath_rcvtidcnt, rtmp); | ||
355 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidbase); | ||
356 | if (rtmp != dd->ipath_rcvtidbase) | ||
357 | dev_info(&dd->pcidev->dev, "tidbase was %u before " | ||
358 | "reset, now %u, using original\n", | ||
359 | dd->ipath_rcvtidbase, rtmp); | ||
360 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrcnt); | ||
361 | if (rtmp != dd->ipath_rcvegrcnt) | ||
362 | dev_info(&dd->pcidev->dev, "egrcnt was %u before " | ||
363 | "reset, now %u, using original\n", | ||
364 | dd->ipath_rcvegrcnt, rtmp); | ||
365 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrbase); | ||
366 | if (rtmp != dd->ipath_rcvegrbase) | ||
367 | dev_info(&dd->pcidev->dev, "egrbase was %u before " | ||
368 | "reset, now %u, using original\n", | ||
369 | dd->ipath_rcvegrbase, rtmp); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static int init_pioavailregs(struct ipath_devdata *dd) | ||
375 | { | ||
376 | int ret; | ||
377 | |||
378 | dd->ipath_pioavailregs_dma = dma_alloc_coherent( | ||
379 | &dd->pcidev->dev, PAGE_SIZE, &dd->ipath_pioavailregs_phys, | ||
380 | GFP_KERNEL); | ||
381 | if (!dd->ipath_pioavailregs_dma) { | ||
382 | ipath_dev_err(dd, "failed to allocate PIOavail reg area " | ||
383 | "in memory\n"); | ||
384 | ret = -ENOMEM; | ||
385 | goto done; | ||
386 | } | ||
387 | |||
388 | /* | ||
389 | * we really want L2 cache aligned, but for current CPUs of | ||
390 | * interest, they are the same. | ||
391 | */ | ||
392 | dd->ipath_statusp = (u64 *) | ||
393 | ((char *)dd->ipath_pioavailregs_dma + | ||
394 | ((2 * L1_CACHE_BYTES + | ||
395 | dd->ipath_pioavregs * sizeof(u64)) & ~L1_CACHE_BYTES)); | ||
396 | /* copy the current value now that it's really allocated */ | ||
397 | *dd->ipath_statusp = dd->_ipath_status; | ||
398 | /* | ||
399 | * setup buffer to hold freeze msg, accessible to apps, | ||
400 | * following statusp | ||
401 | */ | ||
402 | dd->ipath_freezemsg = (char *)&dd->ipath_statusp[1]; | ||
403 | /* and its length */ | ||
404 | dd->ipath_freezelen = L1_CACHE_BYTES - sizeof(dd->ipath_statusp[0]); | ||
405 | |||
406 | if (dd->ipath_unit * 64 > (IPATH_PORT0_RCVHDRTAIL_SIZE - 64)) { | ||
407 | ipath_dev_err(dd, "unit %u too large for port 0 " | ||
408 | "rcvhdrtail buffer size\n", dd->ipath_unit); | ||
409 | ret = -ENODEV; | ||
410 | } | ||
411 | else | ||
412 | ret = 0; | ||
413 | |||
414 | /* so we can get current tail in ipath_kreceive(), per chip */ | ||
415 | dd->ipath_hdrqtailptr = &ipath_port0_rcvhdrtail[ | ||
416 | dd->ipath_unit * (64 / sizeof(*ipath_port0_rcvhdrtail))]; | ||
417 | done: | ||
418 | return ret; | ||
419 | } | ||
420 | |||
421 | /** | ||
422 | * init_shadow_tids - allocate the shadow TID array | ||
423 | * @dd: the infinipath device | ||
424 | * | ||
425 | * allocate the shadow TID array, so we can ipath_munlock previous | ||
426 | * entries. It may make more sense to move the pageshadow to the | ||
427 | * port data structure, so we only allocate memory for ports actually | ||
428 | * in use, since we at 8k per port, now. | ||
429 | */ | ||
430 | static void init_shadow_tids(struct ipath_devdata *dd) | ||
431 | { | ||
432 | dd->ipath_pageshadow = (struct page **) | ||
433 | vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt * | ||
434 | sizeof(struct page *)); | ||
435 | if (!dd->ipath_pageshadow) | ||
436 | ipath_dev_err(dd, "failed to allocate shadow page * " | ||
437 | "array, no expected sends!\n"); | ||
438 | else | ||
439 | memset(dd->ipath_pageshadow, 0, | ||
440 | dd->ipath_cfgports * dd->ipath_rcvtidcnt * | ||
441 | sizeof(struct page *)); | ||
442 | } | ||
443 | |||
444 | static void enable_chip(struct ipath_devdata *dd, | ||
445 | struct ipath_portdata *pd, int reinit) | ||
446 | { | ||
447 | u32 val; | ||
448 | int i; | ||
449 | |||
450 | if (!reinit) { | ||
451 | init_waitqueue_head(&ipath_sma_state_wait); | ||
452 | } | ||
453 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
454 | dd->ipath_rcvctrl); | ||
455 | |||
456 | /* Enable PIO send, and update of PIOavail regs to memory. */ | ||
457 | dd->ipath_sendctrl = INFINIPATH_S_PIOENABLE | | ||
458 | INFINIPATH_S_PIOBUFAVAILUPD; | ||
459 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
460 | dd->ipath_sendctrl); | ||
461 | |||
462 | /* | ||
463 | * enable port 0 receive, and receive interrupt. other ports | ||
464 | * done as user opens and inits them. | ||
465 | */ | ||
466 | dd->ipath_rcvctrl = INFINIPATH_R_TAILUPD | | ||
467 | (1ULL << INFINIPATH_R_PORTENABLE_SHIFT) | | ||
468 | (1ULL << INFINIPATH_R_INTRAVAIL_SHIFT); | ||
469 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
470 | dd->ipath_rcvctrl); | ||
471 | |||
472 | /* | ||
473 | * now ready for use. this should be cleared whenever we | ||
474 | * detect a reset, or initiate one. | ||
475 | */ | ||
476 | dd->ipath_flags |= IPATH_INITTED; | ||
477 | |||
478 | /* | ||
479 | * init our shadow copies of head from tail values, and write | ||
480 | * head values to match. | ||
481 | */ | ||
482 | val = ipath_read_ureg32(dd, ur_rcvegrindextail, 0); | ||
483 | (void)ipath_write_ureg(dd, ur_rcvegrindexhead, val, 0); | ||
484 | dd->ipath_port0head = ipath_read_ureg32(dd, ur_rcvhdrtail, 0); | ||
485 | |||
486 | /* Initialize so we interrupt on next packet received */ | ||
487 | (void)ipath_write_ureg(dd, ur_rcvhdrhead, | ||
488 | dd->ipath_rhdrhead_intr_off | | ||
489 | dd->ipath_port0head, 0); | ||
490 | |||
491 | /* | ||
492 | * by now pioavail updates to memory should have occurred, so | ||
493 | * copy them into our working/shadow registers; this is in | ||
494 | * case something went wrong with abort, but mostly to get the | ||
495 | * initial values of the generation bit correct. | ||
496 | */ | ||
497 | for (i = 0; i < dd->ipath_pioavregs; i++) { | ||
498 | __le64 val; | ||
499 | |||
500 | /* | ||
501 | * Chip Errata bug 6641; even and odd qwords>3 are swapped. | ||
502 | */ | ||
503 | if (i > 3) { | ||
504 | if (i & 1) | ||
505 | val = dd->ipath_pioavailregs_dma[i - 1]; | ||
506 | else | ||
507 | val = dd->ipath_pioavailregs_dma[i + 1]; | ||
508 | } | ||
509 | else | ||
510 | val = dd->ipath_pioavailregs_dma[i]; | ||
511 | dd->ipath_pioavailshadow[i] = le64_to_cpu(val); | ||
512 | } | ||
513 | /* can get counters, stats, etc. */ | ||
514 | dd->ipath_flags |= IPATH_PRESENT; | ||
515 | } | ||
516 | |||
517 | static int init_housekeeping(struct ipath_devdata *dd, | ||
518 | struct ipath_portdata **pdp, int reinit) | ||
519 | { | ||
520 | char boardn[32]; | ||
521 | int ret = 0; | ||
522 | |||
523 | /* | ||
524 | * have to clear shadow copies of registers at init that are | ||
525 | * not otherwise set here, or all kinds of bizarre things | ||
526 | * happen with driver on chip reset | ||
527 | */ | ||
528 | dd->ipath_rcvhdrsize = 0; | ||
529 | |||
530 | /* | ||
531 | * Don't clear ipath_flags as 8bit mode was set before | ||
532 | * entering this func. However, we do set the linkstate to | ||
533 | * unknown, so we can watch for a transition. | ||
534 | */ | ||
535 | dd->ipath_flags |= IPATH_LINKUNK; | ||
536 | dd->ipath_flags &= ~(IPATH_LINKACTIVE | IPATH_LINKARMED | | ||
537 | IPATH_LINKDOWN | IPATH_LINKINIT); | ||
538 | |||
539 | ipath_cdbg(VERBOSE, "Try to read spc chip revision\n"); | ||
540 | dd->ipath_revision = | ||
541 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_revision); | ||
542 | |||
543 | /* | ||
544 | * set up fundamental info we need to use the chip; we assume | ||
545 | * if the revision reg and these regs are OK, we don't need to | ||
546 | * special case the rest | ||
547 | */ | ||
548 | dd->ipath_sregbase = | ||
549 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_sendregbase); | ||
550 | dd->ipath_cregbase = | ||
551 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_counterregbase); | ||
552 | dd->ipath_uregbase = | ||
553 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_userregbase); | ||
554 | ipath_cdbg(VERBOSE, "ipath_kregbase %p, sendbase %x usrbase %x, " | ||
555 | "cntrbase %x\n", dd->ipath_kregbase, dd->ipath_sregbase, | ||
556 | dd->ipath_uregbase, dd->ipath_cregbase); | ||
557 | if ((dd->ipath_revision & 0xffffffff) == 0xffffffff | ||
558 | || (dd->ipath_sregbase & 0xffffffff) == 0xffffffff | ||
559 | || (dd->ipath_cregbase & 0xffffffff) == 0xffffffff | ||
560 | || (dd->ipath_uregbase & 0xffffffff) == 0xffffffff) { | ||
561 | ipath_dev_err(dd, "Register read failures from chip, " | ||
562 | "giving up initialization\n"); | ||
563 | ret = -ENODEV; | ||
564 | goto done; | ||
565 | } | ||
566 | |||
567 | /* clear the initial reset flag, in case first driver load */ | ||
568 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, | ||
569 | INFINIPATH_E_RESET); | ||
570 | |||
571 | if (reinit) | ||
572 | ret = init_chip_reset(dd, pdp); | ||
573 | else | ||
574 | ret = init_chip_first(dd, pdp); | ||
575 | |||
576 | if (ret) | ||
577 | goto done; | ||
578 | |||
579 | ipath_cdbg(VERBOSE, "Revision %llx (PCI %x), %u ports, %u tids, " | ||
580 | "%u egrtids\n", (unsigned long long) dd->ipath_revision, | ||
581 | dd->ipath_pcirev, dd->ipath_portcnt, dd->ipath_rcvtidcnt, | ||
582 | dd->ipath_rcvegrcnt); | ||
583 | |||
584 | if (((dd->ipath_revision >> INFINIPATH_R_SOFTWARE_SHIFT) & | ||
585 | INFINIPATH_R_SOFTWARE_MASK) != IPATH_CHIP_SWVERSION) { | ||
586 | ipath_dev_err(dd, "Driver only handles version %d, " | ||
587 | "chip swversion is %d (%llx), failng\n", | ||
588 | IPATH_CHIP_SWVERSION, | ||
589 | (int)(dd->ipath_revision >> | ||
590 | INFINIPATH_R_SOFTWARE_SHIFT) & | ||
591 | INFINIPATH_R_SOFTWARE_MASK, | ||
592 | (unsigned long long) dd->ipath_revision); | ||
593 | ret = -ENOSYS; | ||
594 | goto done; | ||
595 | } | ||
596 | dd->ipath_majrev = (u8) ((dd->ipath_revision >> | ||
597 | INFINIPATH_R_CHIPREVMAJOR_SHIFT) & | ||
598 | INFINIPATH_R_CHIPREVMAJOR_MASK); | ||
599 | dd->ipath_minrev = (u8) ((dd->ipath_revision >> | ||
600 | INFINIPATH_R_CHIPREVMINOR_SHIFT) & | ||
601 | INFINIPATH_R_CHIPREVMINOR_MASK); | ||
602 | dd->ipath_boardrev = (u8) ((dd->ipath_revision >> | ||
603 | INFINIPATH_R_BOARDID_SHIFT) & | ||
604 | INFINIPATH_R_BOARDID_MASK); | ||
605 | |||
606 | ret = dd->ipath_f_get_boardname(dd, boardn, sizeof boardn); | ||
607 | |||
608 | snprintf(dd->ipath_boardversion, sizeof(dd->ipath_boardversion), | ||
609 | "Driver %u.%u, %s, InfiniPath%u %u.%u, PCI %u, " | ||
610 | "SW Compat %u\n", | ||
611 | IPATH_CHIP_VERS_MAJ, IPATH_CHIP_VERS_MIN, boardn, | ||
612 | (unsigned)(dd->ipath_revision >> INFINIPATH_R_ARCH_SHIFT) & | ||
613 | INFINIPATH_R_ARCH_MASK, | ||
614 | dd->ipath_majrev, dd->ipath_minrev, dd->ipath_pcirev, | ||
615 | (unsigned)(dd->ipath_revision >> | ||
616 | INFINIPATH_R_SOFTWARE_SHIFT) & | ||
617 | INFINIPATH_R_SOFTWARE_MASK); | ||
618 | |||
619 | ipath_dbg("%s", dd->ipath_boardversion); | ||
620 | |||
621 | done: | ||
622 | return ret; | ||
623 | } | ||
624 | |||
625 | |||
626 | /** | ||
627 | * ipath_init_chip - do the actual initialization sequence on the chip | ||
628 | * @dd: the infinipath device | ||
629 | * @reinit: reinitializing, so don't allocate new memory | ||
630 | * | ||
631 | * Do the actual initialization sequence on the chip. This is done | ||
632 | * both from the init routine called from the PCI infrastructure, and | ||
633 | * when we reset the chip, or detect that it was reset internally, | ||
634 | * or it's administratively re-enabled. | ||
635 | * | ||
636 | * Memory allocation here and in called routines is only done in | ||
637 | * the first case (reinit == 0). We have to be careful, because even | ||
638 | * without memory allocation, we need to re-write all the chip registers | ||
639 | * TIDs, etc. after the reset or enable has completed. | ||
640 | */ | ||
641 | int ipath_init_chip(struct ipath_devdata *dd, int reinit) | ||
642 | { | ||
643 | int ret = 0, i; | ||
644 | u32 val32, kpiobufs; | ||
645 | u64 val, atmp; | ||
646 | struct ipath_portdata *pd = NULL; /* keep gcc4 happy */ | ||
647 | |||
648 | ret = init_housekeeping(dd, &pd, reinit); | ||
649 | if (ret) | ||
650 | goto done; | ||
651 | |||
652 | /* | ||
653 | * we ignore most issues after reporting them, but have to specially | ||
654 | * handle hardware-disabled chips. | ||
655 | */ | ||
656 | if (ret == 2) { | ||
657 | /* unique error, known to ipath_init_one */ | ||
658 | ret = -EPERM; | ||
659 | goto done; | ||
660 | } | ||
661 | |||
662 | /* | ||
663 | * We could bump this to allow for full rcvegrcnt + rcvtidcnt, | ||
664 | * but then it no longer nicely fits power of two, and since | ||
665 | * we now use routines that backend onto __get_free_pages, the | ||
666 | * rest would be wasted. | ||
667 | */ | ||
668 | dd->ipath_rcvhdrcnt = dd->ipath_rcvegrcnt; | ||
669 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrcnt, | ||
670 | dd->ipath_rcvhdrcnt); | ||
671 | |||
672 | /* | ||
673 | * Set up the shadow copies of the piobufavail registers, | ||
674 | * which we compare against the chip registers for now, and | ||
675 | * the in memory DMA'ed copies of the registers. This has to | ||
676 | * be done early, before we calculate lastport, etc. | ||
677 | */ | ||
678 | val = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k; | ||
679 | /* | ||
680 | * calc number of pioavail registers, and save it; we have 2 | ||
681 | * bits per buffer. | ||
682 | */ | ||
683 | dd->ipath_pioavregs = ALIGN(val, sizeof(u64) * BITS_PER_BYTE / 2) | ||
684 | / (sizeof(u64) * BITS_PER_BYTE / 2); | ||
685 | if (!ipath_kpiobufs) /* have to have at least 1, for SMA */ | ||
686 | kpiobufs = ipath_kpiobufs = 1; | ||
687 | else if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) < | ||
688 | (dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT)) { | ||
689 | dev_info(&dd->pcidev->dev, "Too few PIO buffers (%u) " | ||
690 | "for %u ports to have %u each!\n", | ||
691 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k, | ||
692 | dd->ipath_cfgports, IPATH_MIN_USER_PORT_BUFCNT); | ||
693 | kpiobufs = 1; /* reserve just the minimum for SMA/ether */ | ||
694 | } else | ||
695 | kpiobufs = ipath_kpiobufs; | ||
696 | |||
697 | if (kpiobufs > | ||
698 | (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - | ||
699 | (dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT))) { | ||
700 | i = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - | ||
701 | (dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT); | ||
702 | if (i < 0) | ||
703 | i = 0; | ||
704 | dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs for " | ||
705 | "kernel leaves too few for %d user ports " | ||
706 | "(%d each); using %u\n", kpiobufs, | ||
707 | dd->ipath_cfgports - 1, | ||
708 | IPATH_MIN_USER_PORT_BUFCNT, i); | ||
709 | /* | ||
710 | * shouldn't change ipath_kpiobufs, because could be | ||
711 | * different for different devices... | ||
712 | */ | ||
713 | kpiobufs = i; | ||
714 | } | ||
715 | dd->ipath_lastport_piobuf = | ||
716 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - kpiobufs; | ||
717 | dd->ipath_pbufsport = dd->ipath_cfgports > 1 | ||
718 | ? dd->ipath_lastport_piobuf / (dd->ipath_cfgports - 1) | ||
719 | : 0; | ||
720 | val32 = dd->ipath_lastport_piobuf - | ||
721 | (dd->ipath_pbufsport * (dd->ipath_cfgports - 1)); | ||
722 | if (val32 > 0) { | ||
723 | ipath_dbg("allocating %u pbufs/port leaves %u unused, " | ||
724 | "add to kernel\n", dd->ipath_pbufsport, val32); | ||
725 | dd->ipath_lastport_piobuf -= val32; | ||
726 | ipath_dbg("%u pbufs/port leaves %u unused, add to kernel\n", | ||
727 | dd->ipath_pbufsport, val32); | ||
728 | } | ||
729 | dd->ipath_lastpioindex = dd->ipath_lastport_piobuf; | ||
730 | ipath_cdbg(VERBOSE, "%d PIO bufs for kernel out of %d total %u " | ||
731 | "each for %u user ports\n", kpiobufs, | ||
732 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k, | ||
733 | dd->ipath_pbufsport, dd->ipath_cfgports - 1); | ||
734 | |||
735 | dd->ipath_f_early_init(dd); | ||
736 | |||
737 | /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be | ||
738 | * done after early_init */ | ||
739 | dd->ipath_hdrqlast = | ||
740 | dd->ipath_rcvhdrentsize * (dd->ipath_rcvhdrcnt - 1); | ||
741 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrentsize, | ||
742 | dd->ipath_rcvhdrentsize); | ||
743 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrsize, | ||
744 | dd->ipath_rcvhdrsize); | ||
745 | |||
746 | if (!reinit) { | ||
747 | ret = init_pioavailregs(dd); | ||
748 | init_shadow_tids(dd); | ||
749 | if (ret) | ||
750 | goto done; | ||
751 | } | ||
752 | |||
753 | (void)ipath_write_kreg(dd, dd->ipath_kregs->kr_sendpioavailaddr, | ||
754 | dd->ipath_pioavailregs_phys); | ||
755 | /* | ||
756 | * this is to detect s/w errors, which the h/w works around by | ||
757 | * ignoring the low 6 bits of address, if it wasn't aligned. | ||
758 | */ | ||
759 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpioavailaddr); | ||
760 | if (val != dd->ipath_pioavailregs_phys) { | ||
761 | ipath_dev_err(dd, "Catastrophic software error, " | ||
762 | "SendPIOAvailAddr written as %lx, " | ||
763 | "read back as %llx\n", | ||
764 | (unsigned long) dd->ipath_pioavailregs_phys, | ||
765 | (unsigned long long) val); | ||
766 | ret = -EINVAL; | ||
767 | goto done; | ||
768 | } | ||
769 | |||
770 | val = ipath_port0_rcvhdrtail_dma + dd->ipath_unit * 64; | ||
771 | |||
772 | /* verify that the alignment requirement was met */ | ||
773 | ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdrtailaddr, | ||
774 | 0, val); | ||
775 | atmp = ipath_read_kreg64_port( | ||
776 | dd, dd->ipath_kregs->kr_rcvhdrtailaddr, 0); | ||
777 | if (val != atmp) { | ||
778 | ipath_dev_err(dd, "Catastrophic software error, " | ||
779 | "RcvHdrTailAddr0 written as %llx, " | ||
780 | "read back as %llx from %x\n", | ||
781 | (unsigned long long) val, | ||
782 | (unsigned long long) atmp, | ||
783 | dd->ipath_kregs->kr_rcvhdrtailaddr); | ||
784 | ret = -EINVAL; | ||
785 | goto done; | ||
786 | } | ||
787 | |||
788 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvbthqp, IPATH_KD_QP); | ||
789 | |||
790 | /* | ||
791 | * make sure we are not in freeze, and PIO send enabled, so | ||
792 | * writes to pbc happen | ||
793 | */ | ||
794 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, 0ULL); | ||
795 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, | ||
796 | ~0ULL&~INFINIPATH_HWE_MEMBISTFAILED); | ||
797 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0ULL); | ||
798 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
799 | INFINIPATH_S_PIOENABLE); | ||
800 | |||
801 | /* | ||
802 | * before error clears, since we expect serdes pll errors during | ||
803 | * this, the first time after reset | ||
804 | */ | ||
805 | if (bringup_link(dd)) { | ||
806 | dev_info(&dd->pcidev->dev, "Failed to bringup IB link\n"); | ||
807 | ret = -ENETDOWN; | ||
808 | goto done; | ||
809 | } | ||
810 | |||
811 | /* | ||
812 | * clear any "expected" hwerrs from reset and/or initialization | ||
813 | * clear any that aren't enabled (at least this once), and then | ||
814 | * set the enable mask | ||
815 | */ | ||
816 | dd->ipath_f_init_hwerrors(dd); | ||
817 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, | ||
818 | ~0ULL&~INFINIPATH_HWE_MEMBISTFAILED); | ||
819 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, | ||
820 | dd->ipath_hwerrmask); | ||
821 | |||
822 | dd->ipath_maskederrs = dd->ipath_ignorederrs; | ||
823 | /* clear all */ | ||
824 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, -1LL); | ||
825 | /* enable errors that are masked, at least this first time. */ | ||
826 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, | ||
827 | ~dd->ipath_maskederrs); | ||
828 | /* clear any interrups up to this point (ints still not enabled) */ | ||
829 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL); | ||
830 | |||
831 | ipath_stats.sps_lid[dd->ipath_unit] = dd->ipath_lid; | ||
832 | |||
833 | /* | ||
834 | * Set up the port 0 (kernel) rcvhdr q and egr TIDs. If doing | ||
835 | * re-init, the simplest way to handle this is to free | ||
836 | * existing, and re-allocate. | ||
837 | */ | ||
838 | if (reinit) | ||
839 | ipath_free_pddata(dd, 0, 0); | ||
840 | dd->ipath_f_tidtemplate(dd); | ||
841 | ret = ipath_create_rcvhdrq(dd, pd); | ||
842 | if (!ret) | ||
843 | ret = create_port0_egr(dd); | ||
844 | if (ret) | ||
845 | ipath_dev_err(dd, "failed to allocate port 0 (kernel) " | ||
846 | "rcvhdrq and/or egr bufs\n"); | ||
847 | else | ||
848 | enable_chip(dd, pd, reinit); | ||
849 | |||
850 | /* | ||
851 | * cause retrigger of pending interrupts ignored during init, | ||
852 | * even if we had errors | ||
853 | */ | ||
854 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL); | ||
855 | |||
856 | if(!dd->ipath_stats_timer_active) { | ||
857 | /* | ||
858 | * first init, or after an admin disable/enable | ||
859 | * set up stats retrieval timer, even if we had errors | ||
860 | * in last portion of setup | ||
861 | */ | ||
862 | init_timer(&dd->ipath_stats_timer); | ||
863 | dd->ipath_stats_timer.function = ipath_get_faststats; | ||
864 | dd->ipath_stats_timer.data = (unsigned long) dd; | ||
865 | /* every 5 seconds; */ | ||
866 | dd->ipath_stats_timer.expires = jiffies + 5 * HZ; | ||
867 | /* takes ~16 seconds to overflow at full IB 4x bandwdith */ | ||
868 | add_timer(&dd->ipath_stats_timer); | ||
869 | dd->ipath_stats_timer_active = 1; | ||
870 | } | ||
871 | |||
872 | done: | ||
873 | if (!ret) { | ||
874 | ipath_get_guid(dd); | ||
875 | *dd->ipath_statusp |= IPATH_STATUS_CHIP_PRESENT; | ||
876 | if (!dd->ipath_f_intrsetup(dd)) { | ||
877 | /* now we can enable all interrupts from the chip */ | ||
878 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, | ||
879 | -1LL); | ||
880 | /* force re-interrupt of any pending interrupts. */ | ||
881 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, | ||
882 | 0ULL); | ||
883 | /* chip is usable; mark it as initialized */ | ||
884 | *dd->ipath_statusp |= IPATH_STATUS_INITTED; | ||
885 | } else | ||
886 | ipath_dev_err(dd, "No interrupts enabled, couldn't " | ||
887 | "setup interrupt address\n"); | ||
888 | |||
889 | if (dd->ipath_cfgports > ipath_stats.sps_nports) | ||
890 | /* | ||
891 | * sps_nports is a global, so, we set it to | ||
892 | * the highest number of ports of any of the | ||
893 | * chips we find; we never decrement it, at | ||
894 | * least for now. Since this might have changed | ||
895 | * over disable/enable or prior to reset, always | ||
896 | * do the check and potentially adjust. | ||
897 | */ | ||
898 | ipath_stats.sps_nports = dd->ipath_cfgports; | ||
899 | } else | ||
900 | ipath_dbg("Failed (%d) to initialize chip\n", ret); | ||
901 | |||
902 | /* if ret is non-zero, we probably should do some cleanup | ||
903 | here... */ | ||
904 | return ret; | ||
905 | } | ||
906 | |||
907 | static int ipath_set_kpiobufs(const char *str, struct kernel_param *kp) | ||
908 | { | ||
909 | struct ipath_devdata *dd; | ||
910 | unsigned long flags; | ||
911 | unsigned short val; | ||
912 | int ret; | ||
913 | |||
914 | ret = ipath_parse_ushort(str, &val); | ||
915 | |||
916 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
917 | |||
918 | if (ret < 0) | ||
919 | goto bail; | ||
920 | |||
921 | if (val == 0) { | ||
922 | ret = -EINVAL; | ||
923 | goto bail; | ||
924 | } | ||
925 | |||
926 | list_for_each_entry(dd, &ipath_dev_list, ipath_list) { | ||
927 | if (dd->ipath_kregbase) | ||
928 | continue; | ||
929 | if (val > (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - | ||
930 | (dd->ipath_cfgports * | ||
931 | IPATH_MIN_USER_PORT_BUFCNT))) | ||
932 | { | ||
933 | ipath_dev_err( | ||
934 | dd, | ||
935 | "Allocating %d PIO bufs for kernel leaves " | ||
936 | "too few for %d user ports (%d each)\n", | ||
937 | val, dd->ipath_cfgports - 1, | ||
938 | IPATH_MIN_USER_PORT_BUFCNT); | ||
939 | ret = -EINVAL; | ||
940 | goto bail; | ||
941 | } | ||
942 | dd->ipath_lastport_piobuf = | ||
943 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - val; | ||
944 | } | ||
945 | |||
946 | ret = 0; | ||
947 | bail: | ||
948 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
949 | |||
950 | return ret; | ||
951 | } | ||