diff options
Diffstat (limited to 'drivers/net/mlx4/reset.c')
-rw-r--r-- | drivers/net/mlx4/reset.c | 185 |
1 files changed, 0 insertions, 185 deletions
diff --git a/drivers/net/mlx4/reset.c b/drivers/net/mlx4/reset.c deleted file mode 100644 index 11e7c1cb99bf..000000000000 --- a/drivers/net/mlx4/reset.c +++ /dev/null | |||
@@ -1,185 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the | ||
9 | * OpenIB.org BSD license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or | ||
12 | * without modification, are permitted provided that the following | ||
13 | * conditions are met: | ||
14 | * | ||
15 | * - Redistributions of source code must retain the above | ||
16 | * copyright notice, this list of conditions and the following | ||
17 | * disclaimer. | ||
18 | * | ||
19 | * - Redistributions in binary form must reproduce the above | ||
20 | * copyright notice, this list of conditions and the following | ||
21 | * disclaimer in the documentation and/or other materials | ||
22 | * provided with the distribution. | ||
23 | * | ||
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
27 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
28 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
29 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
30 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
31 | * SOFTWARE. | ||
32 | */ | ||
33 | |||
34 | #include <linux/errno.h> | ||
35 | #include <linux/pci.h> | ||
36 | #include <linux/delay.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/jiffies.h> | ||
39 | |||
40 | #include "mlx4.h" | ||
41 | |||
42 | int mlx4_reset(struct mlx4_dev *dev) | ||
43 | { | ||
44 | void __iomem *reset; | ||
45 | u32 *hca_header = NULL; | ||
46 | int pcie_cap; | ||
47 | u16 devctl; | ||
48 | u16 linkctl; | ||
49 | u16 vendor; | ||
50 | unsigned long end; | ||
51 | u32 sem; | ||
52 | int i; | ||
53 | int err = 0; | ||
54 | |||
55 | #define MLX4_RESET_BASE 0xf0000 | ||
56 | #define MLX4_RESET_SIZE 0x400 | ||
57 | #define MLX4_SEM_OFFSET 0x3fc | ||
58 | #define MLX4_RESET_OFFSET 0x10 | ||
59 | #define MLX4_RESET_VALUE swab32(1) | ||
60 | |||
61 | #define MLX4_SEM_TIMEOUT_JIFFIES (10 * HZ) | ||
62 | #define MLX4_RESET_TIMEOUT_JIFFIES (2 * HZ) | ||
63 | |||
64 | /* | ||
65 | * Reset the chip. This is somewhat ugly because we have to | ||
66 | * save off the PCI header before reset and then restore it | ||
67 | * after the chip reboots. We skip config space offsets 22 | ||
68 | * and 23 since those have a special meaning. | ||
69 | */ | ||
70 | |||
71 | /* Do we need to save off the full 4K PCI Express header?? */ | ||
72 | hca_header = kmalloc(256, GFP_KERNEL); | ||
73 | if (!hca_header) { | ||
74 | err = -ENOMEM; | ||
75 | mlx4_err(dev, "Couldn't allocate memory to save HCA " | ||
76 | "PCI header, aborting.\n"); | ||
77 | goto out; | ||
78 | } | ||
79 | |||
80 | pcie_cap = pci_pcie_cap(dev->pdev); | ||
81 | |||
82 | for (i = 0; i < 64; ++i) { | ||
83 | if (i == 22 || i == 23) | ||
84 | continue; | ||
85 | if (pci_read_config_dword(dev->pdev, i * 4, hca_header + i)) { | ||
86 | err = -ENODEV; | ||
87 | mlx4_err(dev, "Couldn't save HCA " | ||
88 | "PCI header, aborting.\n"); | ||
89 | goto out; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | reset = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_RESET_BASE, | ||
94 | MLX4_RESET_SIZE); | ||
95 | if (!reset) { | ||
96 | err = -ENOMEM; | ||
97 | mlx4_err(dev, "Couldn't map HCA reset register, aborting.\n"); | ||
98 | goto out; | ||
99 | } | ||
100 | |||
101 | /* grab HW semaphore to lock out flash updates */ | ||
102 | end = jiffies + MLX4_SEM_TIMEOUT_JIFFIES; | ||
103 | do { | ||
104 | sem = readl(reset + MLX4_SEM_OFFSET); | ||
105 | if (!sem) | ||
106 | break; | ||
107 | |||
108 | msleep(1); | ||
109 | } while (time_before(jiffies, end)); | ||
110 | |||
111 | if (sem) { | ||
112 | mlx4_err(dev, "Failed to obtain HW semaphore, aborting\n"); | ||
113 | err = -EAGAIN; | ||
114 | iounmap(reset); | ||
115 | goto out; | ||
116 | } | ||
117 | |||
118 | /* actually hit reset */ | ||
119 | writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET); | ||
120 | iounmap(reset); | ||
121 | |||
122 | /* Docs say to wait one second before accessing device */ | ||
123 | msleep(1000); | ||
124 | |||
125 | end = jiffies + MLX4_RESET_TIMEOUT_JIFFIES; | ||
126 | do { | ||
127 | if (!pci_read_config_word(dev->pdev, PCI_VENDOR_ID, &vendor) && | ||
128 | vendor != 0xffff) | ||
129 | break; | ||
130 | |||
131 | msleep(1); | ||
132 | } while (time_before(jiffies, end)); | ||
133 | |||
134 | if (vendor == 0xffff) { | ||
135 | err = -ENODEV; | ||
136 | mlx4_err(dev, "PCI device did not come back after reset, " | ||
137 | "aborting.\n"); | ||
138 | goto out; | ||
139 | } | ||
140 | |||
141 | /* Now restore the PCI headers */ | ||
142 | if (pcie_cap) { | ||
143 | devctl = hca_header[(pcie_cap + PCI_EXP_DEVCTL) / 4]; | ||
144 | if (pci_write_config_word(dev->pdev, pcie_cap + PCI_EXP_DEVCTL, | ||
145 | devctl)) { | ||
146 | err = -ENODEV; | ||
147 | mlx4_err(dev, "Couldn't restore HCA PCI Express " | ||
148 | "Device Control register, aborting.\n"); | ||
149 | goto out; | ||
150 | } | ||
151 | linkctl = hca_header[(pcie_cap + PCI_EXP_LNKCTL) / 4]; | ||
152 | if (pci_write_config_word(dev->pdev, pcie_cap + PCI_EXP_LNKCTL, | ||
153 | linkctl)) { | ||
154 | err = -ENODEV; | ||
155 | mlx4_err(dev, "Couldn't restore HCA PCI Express " | ||
156 | "Link control register, aborting.\n"); | ||
157 | goto out; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | for (i = 0; i < 16; ++i) { | ||
162 | if (i * 4 == PCI_COMMAND) | ||
163 | continue; | ||
164 | |||
165 | if (pci_write_config_dword(dev->pdev, i * 4, hca_header[i])) { | ||
166 | err = -ENODEV; | ||
167 | mlx4_err(dev, "Couldn't restore HCA reg %x, " | ||
168 | "aborting.\n", i); | ||
169 | goto out; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | if (pci_write_config_dword(dev->pdev, PCI_COMMAND, | ||
174 | hca_header[PCI_COMMAND / 4])) { | ||
175 | err = -ENODEV; | ||
176 | mlx4_err(dev, "Couldn't restore HCA COMMAND, " | ||
177 | "aborting.\n"); | ||
178 | goto out; | ||
179 | } | ||
180 | |||
181 | out: | ||
182 | kfree(hca_header); | ||
183 | |||
184 | return err; | ||
185 | } | ||