diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-05-13 03:17:42 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-08-11 05:33:50 -0400 |
commit | 874aeea5d01cac55c160a4e503e3ddb4db030de7 (patch) | |
tree | 2ec67fc737ebc853d954b914a70098ece1ded19b /drivers/net/ethernet/sfc/io.h | |
parent | e689cf4a042772f727450035b102579b0c01bdc7 (diff) |
sfc: Move the Solarflare drivers
Moves the Solarflare drivers into drivers/net/ethernet/sfc/ and
make the necessary Kconfig and Makefile changes.
CC: Steve Hodgson <shodgson@solarflare.com>
CC: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/sfc/io.h')
-rw-r--r-- | drivers/net/ethernet/sfc/io.h | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/drivers/net/ethernet/sfc/io.h b/drivers/net/ethernet/sfc/io.h new file mode 100644 index 000000000000..cc978803d484 --- /dev/null +++ b/drivers/net/ethernet/sfc/io.h | |||
@@ -0,0 +1,299 @@ | |||
1 | /**************************************************************************** | ||
2 | * Driver for Solarflare Solarstorm network controllers and boards | ||
3 | * Copyright 2005-2006 Fen Systems Ltd. | ||
4 | * Copyright 2006-2010 Solarflare Communications Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation, incorporated herein by reference. | ||
9 | */ | ||
10 | |||
11 | #ifndef EFX_IO_H | ||
12 | #define EFX_IO_H | ||
13 | |||
14 | #include <linux/io.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | |||
17 | /************************************************************************** | ||
18 | * | ||
19 | * NIC register I/O | ||
20 | * | ||
21 | ************************************************************************** | ||
22 | * | ||
23 | * Notes on locking strategy: | ||
24 | * | ||
25 | * Most CSRs are 128-bit (oword) and therefore cannot be read or | ||
26 | * written atomically. Access from the host is buffered by the Bus | ||
27 | * Interface Unit (BIU). Whenever the host reads from the lowest | ||
28 | * address of such a register, or from the address of a different such | ||
29 | * register, the BIU latches the register's value. Subsequent reads | ||
30 | * from higher addresses of the same register will read the latched | ||
31 | * value. Whenever the host writes part of such a register, the BIU | ||
32 | * collects the written value and does not write to the underlying | ||
33 | * register until all 4 dwords have been written. A similar buffering | ||
34 | * scheme applies to host access to the NIC's 64-bit SRAM. | ||
35 | * | ||
36 | * Access to different CSRs and 64-bit SRAM words must be serialised, | ||
37 | * since interleaved access can result in lost writes or lost | ||
38 | * information from read-to-clear fields. We use efx_nic::biu_lock | ||
39 | * for this. (We could use separate locks for read and write, but | ||
40 | * this is not normally a performance bottleneck.) | ||
41 | * | ||
42 | * The DMA descriptor pointers (RX_DESC_UPD and TX_DESC_UPD) are | ||
43 | * 128-bit but are special-cased in the BIU to avoid the need for | ||
44 | * locking in the host: | ||
45 | * | ||
46 | * - They are write-only. | ||
47 | * - The semantics of writing to these registers are such that | ||
48 | * replacing the low 96 bits with zero does not affect functionality. | ||
49 | * - If the host writes to the last dword address of such a register | ||
50 | * (i.e. the high 32 bits) the underlying register will always be | ||
51 | * written. If the collector and the current write together do not | ||
52 | * provide values for all 128 bits of the register, the low 96 bits | ||
53 | * will be written as zero. | ||
54 | * - If the host writes to the address of any other part of such a | ||
55 | * register while the collector already holds values for some other | ||
56 | * register, the write is discarded and the collector maintains its | ||
57 | * current state. | ||
58 | */ | ||
59 | |||
60 | #if BITS_PER_LONG == 64 | ||
61 | #define EFX_USE_QWORD_IO 1 | ||
62 | #endif | ||
63 | |||
64 | #ifdef EFX_USE_QWORD_IO | ||
65 | static inline void _efx_writeq(struct efx_nic *efx, __le64 value, | ||
66 | unsigned int reg) | ||
67 | { | ||
68 | __raw_writeq((__force u64)value, efx->membase + reg); | ||
69 | } | ||
70 | static inline __le64 _efx_readq(struct efx_nic *efx, unsigned int reg) | ||
71 | { | ||
72 | return (__force __le64)__raw_readq(efx->membase + reg); | ||
73 | } | ||
74 | #endif | ||
75 | |||
76 | static inline void _efx_writed(struct efx_nic *efx, __le32 value, | ||
77 | unsigned int reg) | ||
78 | { | ||
79 | __raw_writel((__force u32)value, efx->membase + reg); | ||
80 | } | ||
81 | static inline __le32 _efx_readd(struct efx_nic *efx, unsigned int reg) | ||
82 | { | ||
83 | return (__force __le32)__raw_readl(efx->membase + reg); | ||
84 | } | ||
85 | |||
86 | /* Write a normal 128-bit CSR, locking as appropriate. */ | ||
87 | static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value, | ||
88 | unsigned int reg) | ||
89 | { | ||
90 | unsigned long flags __attribute__ ((unused)); | ||
91 | |||
92 | netif_vdbg(efx, hw, efx->net_dev, | ||
93 | "writing register %x with " EFX_OWORD_FMT "\n", reg, | ||
94 | EFX_OWORD_VAL(*value)); | ||
95 | |||
96 | spin_lock_irqsave(&efx->biu_lock, flags); | ||
97 | #ifdef EFX_USE_QWORD_IO | ||
98 | _efx_writeq(efx, value->u64[0], reg + 0); | ||
99 | _efx_writeq(efx, value->u64[1], reg + 8); | ||
100 | #else | ||
101 | _efx_writed(efx, value->u32[0], reg + 0); | ||
102 | _efx_writed(efx, value->u32[1], reg + 4); | ||
103 | _efx_writed(efx, value->u32[2], reg + 8); | ||
104 | _efx_writed(efx, value->u32[3], reg + 12); | ||
105 | #endif | ||
106 | wmb(); | ||
107 | mmiowb(); | ||
108 | spin_unlock_irqrestore(&efx->biu_lock, flags); | ||
109 | } | ||
110 | |||
111 | /* Write 64-bit SRAM through the supplied mapping, locking as appropriate. */ | ||
112 | static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase, | ||
113 | efx_qword_t *value, unsigned int index) | ||
114 | { | ||
115 | unsigned int addr = index * sizeof(*value); | ||
116 | unsigned long flags __attribute__ ((unused)); | ||
117 | |||
118 | netif_vdbg(efx, hw, efx->net_dev, | ||
119 | "writing SRAM address %x with " EFX_QWORD_FMT "\n", | ||
120 | addr, EFX_QWORD_VAL(*value)); | ||
121 | |||
122 | spin_lock_irqsave(&efx->biu_lock, flags); | ||
123 | #ifdef EFX_USE_QWORD_IO | ||
124 | __raw_writeq((__force u64)value->u64[0], membase + addr); | ||
125 | #else | ||
126 | __raw_writel((__force u32)value->u32[0], membase + addr); | ||
127 | __raw_writel((__force u32)value->u32[1], membase + addr + 4); | ||
128 | #endif | ||
129 | wmb(); | ||
130 | mmiowb(); | ||
131 | spin_unlock_irqrestore(&efx->biu_lock, flags); | ||
132 | } | ||
133 | |||
134 | /* Write a 32-bit CSR or the last dword of a special 128-bit CSR */ | ||
135 | static inline void efx_writed(struct efx_nic *efx, efx_dword_t *value, | ||
136 | unsigned int reg) | ||
137 | { | ||
138 | netif_vdbg(efx, hw, efx->net_dev, | ||
139 | "writing register %x with "EFX_DWORD_FMT"\n", | ||
140 | reg, EFX_DWORD_VAL(*value)); | ||
141 | |||
142 | /* No lock required */ | ||
143 | _efx_writed(efx, value->u32[0], reg); | ||
144 | wmb(); | ||
145 | } | ||
146 | |||
147 | /* Read a 128-bit CSR, locking as appropriate. */ | ||
148 | static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value, | ||
149 | unsigned int reg) | ||
150 | { | ||
151 | unsigned long flags __attribute__ ((unused)); | ||
152 | |||
153 | spin_lock_irqsave(&efx->biu_lock, flags); | ||
154 | value->u32[0] = _efx_readd(efx, reg + 0); | ||
155 | rmb(); | ||
156 | value->u32[1] = _efx_readd(efx, reg + 4); | ||
157 | value->u32[2] = _efx_readd(efx, reg + 8); | ||
158 | value->u32[3] = _efx_readd(efx, reg + 12); | ||
159 | spin_unlock_irqrestore(&efx->biu_lock, flags); | ||
160 | |||
161 | netif_vdbg(efx, hw, efx->net_dev, | ||
162 | "read from register %x, got " EFX_OWORD_FMT "\n", reg, | ||
163 | EFX_OWORD_VAL(*value)); | ||
164 | } | ||
165 | |||
166 | /* Read 64-bit SRAM through the supplied mapping, locking as appropriate. */ | ||
167 | static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase, | ||
168 | efx_qword_t *value, unsigned int index) | ||
169 | { | ||
170 | unsigned int addr = index * sizeof(*value); | ||
171 | unsigned long flags __attribute__ ((unused)); | ||
172 | |||
173 | spin_lock_irqsave(&efx->biu_lock, flags); | ||
174 | #ifdef EFX_USE_QWORD_IO | ||
175 | value->u64[0] = (__force __le64)__raw_readq(membase + addr); | ||
176 | #else | ||
177 | value->u32[0] = (__force __le32)__raw_readl(membase + addr); | ||
178 | rmb(); | ||
179 | value->u32[1] = (__force __le32)__raw_readl(membase + addr + 4); | ||
180 | #endif | ||
181 | spin_unlock_irqrestore(&efx->biu_lock, flags); | ||
182 | |||
183 | netif_vdbg(efx, hw, efx->net_dev, | ||
184 | "read from SRAM address %x, got "EFX_QWORD_FMT"\n", | ||
185 | addr, EFX_QWORD_VAL(*value)); | ||
186 | } | ||
187 | |||
188 | /* Read a 32-bit CSR or SRAM */ | ||
189 | static inline void efx_readd(struct efx_nic *efx, efx_dword_t *value, | ||
190 | unsigned int reg) | ||
191 | { | ||
192 | value->u32[0] = _efx_readd(efx, reg); | ||
193 | netif_vdbg(efx, hw, efx->net_dev, | ||
194 | "read from register %x, got "EFX_DWORD_FMT"\n", | ||
195 | reg, EFX_DWORD_VAL(*value)); | ||
196 | } | ||
197 | |||
198 | /* Write a 128-bit CSR forming part of a table */ | ||
199 | static inline void efx_writeo_table(struct efx_nic *efx, efx_oword_t *value, | ||
200 | unsigned int reg, unsigned int index) | ||
201 | { | ||
202 | efx_writeo(efx, value, reg + index * sizeof(efx_oword_t)); | ||
203 | } | ||
204 | |||
205 | /* Read a 128-bit CSR forming part of a table */ | ||
206 | static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value, | ||
207 | unsigned int reg, unsigned int index) | ||
208 | { | ||
209 | efx_reado(efx, value, reg + index * sizeof(efx_oword_t)); | ||
210 | } | ||
211 | |||
212 | /* Write a 32-bit CSR forming part of a table, or 32-bit SRAM */ | ||
213 | static inline void efx_writed_table(struct efx_nic *efx, efx_dword_t *value, | ||
214 | unsigned int reg, unsigned int index) | ||
215 | { | ||
216 | efx_writed(efx, value, reg + index * sizeof(efx_oword_t)); | ||
217 | } | ||
218 | |||
219 | /* Read a 32-bit CSR forming part of a table, or 32-bit SRAM */ | ||
220 | static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value, | ||
221 | unsigned int reg, unsigned int index) | ||
222 | { | ||
223 | efx_readd(efx, value, reg + index * sizeof(efx_dword_t)); | ||
224 | } | ||
225 | |||
226 | /* Page-mapped register block size */ | ||
227 | #define EFX_PAGE_BLOCK_SIZE 0x2000 | ||
228 | |||
229 | /* Calculate offset to page-mapped register block */ | ||
230 | #define EFX_PAGED_REG(page, reg) \ | ||
231 | ((page) * EFX_PAGE_BLOCK_SIZE + (reg)) | ||
232 | |||
233 | /* Write the whole of RX_DESC_UPD or TX_DESC_UPD */ | ||
234 | static inline void _efx_writeo_page(struct efx_nic *efx, efx_oword_t *value, | ||
235 | unsigned int reg, unsigned int page) | ||
236 | { | ||
237 | reg = EFX_PAGED_REG(page, reg); | ||
238 | |||
239 | netif_vdbg(efx, hw, efx->net_dev, | ||
240 | "writing register %x with " EFX_OWORD_FMT "\n", reg, | ||
241 | EFX_OWORD_VAL(*value)); | ||
242 | |||
243 | #ifdef EFX_USE_QWORD_IO | ||
244 | _efx_writeq(efx, value->u64[0], reg + 0); | ||
245 | _efx_writeq(efx, value->u64[1], reg + 8); | ||
246 | #else | ||
247 | _efx_writed(efx, value->u32[0], reg + 0); | ||
248 | _efx_writed(efx, value->u32[1], reg + 4); | ||
249 | _efx_writed(efx, value->u32[2], reg + 8); | ||
250 | _efx_writed(efx, value->u32[3], reg + 12); | ||
251 | #endif | ||
252 | wmb(); | ||
253 | } | ||
254 | #define efx_writeo_page(efx, value, reg, page) \ | ||
255 | _efx_writeo_page(efx, value, \ | ||
256 | reg + \ | ||
257 | BUILD_BUG_ON_ZERO((reg) != 0x830 && (reg) != 0xa10), \ | ||
258 | page) | ||
259 | |||
260 | /* Write a page-mapped 32-bit CSR (EVQ_RPTR or the high bits of | ||
261 | * RX_DESC_UPD or TX_DESC_UPD) | ||
262 | */ | ||
263 | static inline void _efx_writed_page(struct efx_nic *efx, efx_dword_t *value, | ||
264 | unsigned int reg, unsigned int page) | ||
265 | { | ||
266 | efx_writed(efx, value, EFX_PAGED_REG(page, reg)); | ||
267 | } | ||
268 | #define efx_writed_page(efx, value, reg, page) \ | ||
269 | _efx_writed_page(efx, value, \ | ||
270 | reg + \ | ||
271 | BUILD_BUG_ON_ZERO((reg) != 0x400 && (reg) != 0x83c \ | ||
272 | && (reg) != 0xa1c), \ | ||
273 | page) | ||
274 | |||
275 | /* Write TIMER_COMMAND. This is a page-mapped 32-bit CSR, but a bug | ||
276 | * in the BIU means that writes to TIMER_COMMAND[0] invalidate the | ||
277 | * collector register. | ||
278 | */ | ||
279 | static inline void _efx_writed_page_locked(struct efx_nic *efx, | ||
280 | efx_dword_t *value, | ||
281 | unsigned int reg, | ||
282 | unsigned int page) | ||
283 | { | ||
284 | unsigned long flags __attribute__ ((unused)); | ||
285 | |||
286 | if (page == 0) { | ||
287 | spin_lock_irqsave(&efx->biu_lock, flags); | ||
288 | efx_writed(efx, value, EFX_PAGED_REG(page, reg)); | ||
289 | spin_unlock_irqrestore(&efx->biu_lock, flags); | ||
290 | } else { | ||
291 | efx_writed(efx, value, EFX_PAGED_REG(page, reg)); | ||
292 | } | ||
293 | } | ||
294 | #define efx_writed_page_locked(efx, value, reg, page) \ | ||
295 | _efx_writed_page_locked(efx, value, \ | ||
296 | reg + BUILD_BUG_ON_ZERO((reg) != 0x420), \ | ||
297 | page) | ||
298 | |||
299 | #endif /* EFX_IO_H */ | ||