diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2008-04-03 20:30:53 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-10-10 18:31:07 -0400 |
commit | cfb739b459a4d982b75f5b92cbe7d2631999e206 (patch) | |
tree | 3baa4860ac0a6937eb39bdedcf803ab44bb697fa /drivers | |
parent | dbc6c2ccb9f0abd6a19406718730ce0f715b2998 (diff) |
Staging: add et131x network driver
This is a driver for the ET1310 network device.
Based on the driver found at https://sourceforge.net/projects/et131x/
Cleaned up immensely by Olaf Hartman <o.hartmann@telovital.com> and Christoph
Hellwig <hch@infradead.org>
Note, the powermanagement options were removed from the vendor provided
driver as they did not build properly at the time.
TODO:
- kernel coding style cleanups
- forward port for latest network driver changes
- kill useless typecasts (e.g. in et1310_phy.c)
- alloc_etherdev is initializing memory with zero?!?
- add_timer call in et131x_netdev.c is correct?
- Add power saving functionality (suspend, sleep, resume)
- Implement a few more kernel Parameter (set mac )
Cc: Olaf Hartmann <o.hartmann@telovital.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dean Adams <dadams1969@gmail.com>
Cc: Victor Soriano <vjsoriano@agere.com>
Cc: Andre-Sebastian Liebe <andre@lianse.eu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
33 files changed, 14261 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 84832feb56f6..4c3789d61a81 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -23,5 +23,6 @@ menuconfig STAGING | |||
23 | 23 | ||
24 | if STAGING | 24 | if STAGING |
25 | 25 | ||
26 | source "drivers/staging/et131x/Kconfig" | ||
26 | 27 | ||
27 | endif # STAGING | 28 | endif # STAGING |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ceb0328a64a8..933b984b5235 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -1,2 +1,3 @@ | |||
1 | # Makefile for staging directory | 1 | # Makefile for staging directory |
2 | 2 | ||
3 | obj-$(CONFIG_ET131X) += et131x/ | ||
diff --git a/drivers/staging/et131x/Kconfig b/drivers/staging/et131x/Kconfig new file mode 100644 index 000000000000..e11cf340856a --- /dev/null +++ b/drivers/staging/et131x/Kconfig | |||
@@ -0,0 +1,18 @@ | |||
1 | config ET131X | ||
2 | tristate "Agere ET-1310 Gigabit Ethernet support" | ||
3 | depends on NETDEV_1000 && PCI | ||
4 | default n | ||
5 | ---help--- | ||
6 | This driver supports Agere ET-1310 ethernet adapters. | ||
7 | |||
8 | To compile this driver as a module, choose M here. The module | ||
9 | will be called et131x. | ||
10 | |||
11 | config ET131X_DEBUG | ||
12 | bool "Enable et131x debugging" | ||
13 | depends on ET131X | ||
14 | default n | ||
15 | ---help--- | ||
16 | Say Y for detailed debug information. | ||
17 | |||
18 | If in doubt, say N. | ||
diff --git a/drivers/staging/et131x/Makefile b/drivers/staging/et131x/Makefile new file mode 100644 index 000000000000..3ad571d8a684 --- /dev/null +++ b/drivers/staging/et131x/Makefile | |||
@@ -0,0 +1,18 @@ | |||
1 | # | ||
2 | # Makefile for the Agere ET-131x ethernet driver | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_ET131X) += et131x.o | ||
6 | |||
7 | et131x-objs := et1310_eeprom.o \ | ||
8 | et1310_jagcore.o \ | ||
9 | et1310_mac.o \ | ||
10 | et1310_phy.o \ | ||
11 | et1310_pm.o \ | ||
12 | et1310_rx.o \ | ||
13 | et1310_tx.o \ | ||
14 | et131x_config.o \ | ||
15 | et131x_debug.o \ | ||
16 | et131x_initpci.o \ | ||
17 | et131x_isr.o \ | ||
18 | et131x_netdev.o | ||
diff --git a/drivers/staging/et131x/README b/drivers/staging/et131x/README new file mode 100644 index 000000000000..28752a502312 --- /dev/null +++ b/drivers/staging/et131x/README | |||
@@ -0,0 +1,25 @@ | |||
1 | This is a driver for the ET1310 network device. | ||
2 | |||
3 | Based on the driver found at https://sourceforge.net/projects/et131x/ | ||
4 | |||
5 | Cleaned up immensely by Olaf Hartman <o.hartmann@telovital.com> and Christoph | ||
6 | Hellwig <hch@infradead.org> | ||
7 | |||
8 | Note, the powermanagement options were removed from the vendor provided | ||
9 | driver as they did not build properly at the time. | ||
10 | |||
11 | TODO: | ||
12 | - kernel coding style cleanups | ||
13 | - forward port for latest network driver changes | ||
14 | - kill useless typecasts (e.g. in et1310_phy.c) | ||
15 | - alloc_etherdev is initializing memory with zero?!? | ||
16 | - add_timer call in et131x_netdev.c is correct? | ||
17 | - Add power saving functionality (suspend, sleep, resume) | ||
18 | - Implement a few more kernel Parameter (set mac ) | ||
19 | |||
20 | Please send patches to: | ||
21 | Greg Kroah-Hartman <gregkh@suse.de> | ||
22 | |||
23 | And Cc: Olaf Hartmann <o.hartmann@telovital.com> as he has this device and can | ||
24 | test any changes. | ||
25 | |||
diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h new file mode 100644 index 000000000000..3c85999d64db --- /dev/null +++ b/drivers/staging/et131x/et1310_address_map.h | |||
@@ -0,0 +1,2399 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_address_map.h - Contains the register mapping for the ET1310 | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #ifndef _ET1310_ADDRESS_MAP_H_ | ||
59 | #define _ET1310_ADDRESS_MAP_H_ | ||
60 | |||
61 | |||
62 | /* START OF GLOBAL REGISTER ADDRESS MAP */ | ||
63 | |||
64 | typedef union _Q_ADDR_t { | ||
65 | u32 value; | ||
66 | struct { | ||
67 | #ifdef _BIT_FIELDS_HTOL | ||
68 | u32 unused:22; // bits 10-31 | ||
69 | u32 addr:10; // bits 0-9 | ||
70 | #else | ||
71 | u32 addr:10; // bits 0-9 | ||
72 | u32 unused:22; // bits 10-31 | ||
73 | #endif | ||
74 | } bits; | ||
75 | } Q_ADDR_t, *PQ_ADDR_t; | ||
76 | |||
77 | /* | ||
78 | * structure for tx queue start address reg in global address map | ||
79 | * located at address 0x0000 | ||
80 | * Defined earlier (Q_ADDR_t) | ||
81 | */ | ||
82 | |||
83 | /* | ||
84 | * structure for tx queue end address reg in global address map | ||
85 | * located at address 0x0004 | ||
86 | * Defined earlier (Q_ADDR_t) | ||
87 | */ | ||
88 | |||
89 | /* | ||
90 | * structure for rx queue start address reg in global address map | ||
91 | * located at address 0x0008 | ||
92 | * Defined earlier (Q_ADDR_t) | ||
93 | */ | ||
94 | |||
95 | /* | ||
96 | * structure for rx queue end address reg in global address map | ||
97 | * located at address 0x000C | ||
98 | * Defined earlier (Q_ADDR_t) | ||
99 | */ | ||
100 | |||
101 | /* | ||
102 | * structure for power management control status reg in global address map | ||
103 | * located at address 0x0010 | ||
104 | */ | ||
105 | typedef union _PM_CSR_t { | ||
106 | u32 value; | ||
107 | struct { | ||
108 | #ifdef _BIT_FIELDS_HTOL | ||
109 | u32 unused:22; // bits 10-31 | ||
110 | u32 pm_jagcore_rx_rdy:1; // bit 9 | ||
111 | u32 pm_jagcore_tx_rdy:1; // bit 8 | ||
112 | u32 pm_phy_lped_en:1; // bit 7 | ||
113 | u32 pm_phy_sw_coma:1; // bit 6 | ||
114 | u32 pm_rxclk_gate:1; // bit 5 | ||
115 | u32 pm_txclk_gate:1; // bit 4 | ||
116 | u32 pm_sysclk_gate:1; // bit 3 | ||
117 | u32 pm_jagcore_rx_en:1; // bit 2 | ||
118 | u32 pm_jagcore_tx_en:1; // bit 1 | ||
119 | u32 pm_gigephy_en:1; // bit 0 | ||
120 | #else | ||
121 | u32 pm_gigephy_en:1; // bit 0 | ||
122 | u32 pm_jagcore_tx_en:1; // bit 1 | ||
123 | u32 pm_jagcore_rx_en:1; // bit 2 | ||
124 | u32 pm_sysclk_gate:1; // bit 3 | ||
125 | u32 pm_txclk_gate:1; // bit 4 | ||
126 | u32 pm_rxclk_gate:1; // bit 5 | ||
127 | u32 pm_phy_sw_coma:1; // bit 6 | ||
128 | u32 pm_phy_lped_en:1; // bit 7 | ||
129 | u32 pm_jagcore_tx_rdy:1; // bit 8 | ||
130 | u32 pm_jagcore_rx_rdy:1; // bit 9 | ||
131 | u32 unused:22; // bits 10-31 | ||
132 | #endif | ||
133 | } bits; | ||
134 | } PM_CSR_t, *PPM_CSR_t; | ||
135 | |||
136 | /* | ||
137 | * structure for interrupt status reg in global address map | ||
138 | * located at address 0x0018 | ||
139 | */ | ||
140 | typedef union _INTERRUPT_t { | ||
141 | u32 value; | ||
142 | struct { | ||
143 | #ifdef _BIT_FIELDS_HTOL | ||
144 | u32 unused5:11; // bits 21-31 | ||
145 | u32 slv_timeout:1; // bit 20 | ||
146 | u32 mac_stat_interrupt:1; // bit 19 | ||
147 | u32 rxmac_interrupt:1; // bit 18 | ||
148 | u32 txmac_interrupt:1; // bit 17 | ||
149 | u32 phy_interrupt:1; // bit 16 | ||
150 | u32 wake_on_lan:1; // bit 15 | ||
151 | u32 watchdog_interrupt:1; // bit 14 | ||
152 | u32 unused4:4; // bits 10-13 | ||
153 | u32 rxdma_err:1; // bit 9 | ||
154 | u32 rxdma_pkt_stat_ring_low:1; // bit 8 | ||
155 | u32 rxdma_fb_ring1_low:1; // bit 7 | ||
156 | u32 rxdma_fb_ring0_low:1; // bit 6 | ||
157 | u32 rxdma_xfr_done:1; // bit 5 | ||
158 | u32 txdma_err:1; // bit 4 | ||
159 | u32 txdma_isr:1; // bit 3 | ||
160 | u32 unused3:1; // bit 2 | ||
161 | u32 unused2:1; // bit 1 | ||
162 | u32 unused1:1; // bit 0 | ||
163 | #else | ||
164 | u32 unused1:1; // bit 0 | ||
165 | u32 unused2:1; // bit 1 | ||
166 | u32 unused3:1; // bit 2 | ||
167 | u32 txdma_isr:1; // bit 3 | ||
168 | u32 txdma_err:1; // bit 4 | ||
169 | u32 rxdma_xfr_done:1; // bit 5 | ||
170 | u32 rxdma_fb_ring0_low:1; // bit 6 | ||
171 | u32 rxdma_fb_ring1_low:1; // bit 7 | ||
172 | u32 rxdma_pkt_stat_ring_low:1; // bit 8 | ||
173 | u32 rxdma_err:1; // bit 9 | ||
174 | u32 unused4:4; // bits 10-13 | ||
175 | u32 watchdog_interrupt:1; // bit 14 | ||
176 | u32 wake_on_lan:1; // bit 15 | ||
177 | u32 phy_interrupt:1; // bit 16 | ||
178 | u32 txmac_interrupt:1; // bit 17 | ||
179 | u32 rxmac_interrupt:1; // bit 18 | ||
180 | u32 mac_stat_interrupt:1; // bit 19 | ||
181 | u32 slv_timeout:1; // bit 20 | ||
182 | u32 unused5:11; // bits 21-31 | ||
183 | #endif | ||
184 | } bits; | ||
185 | } INTERRUPT_t, *PINTERRUPT_t; | ||
186 | |||
187 | /* | ||
188 | * structure for interrupt mask reg in global address map | ||
189 | * located at address 0x001C | ||
190 | * Defined earlier (INTERRUPT_t), but 'watchdog_interrupt' is not used. | ||
191 | */ | ||
192 | |||
193 | /* | ||
194 | * structure for interrupt alias clear mask reg in global address map | ||
195 | * located at address 0x0020 | ||
196 | * Defined earlier (INTERRUPT_t) | ||
197 | */ | ||
198 | |||
199 | /* | ||
200 | * structure for interrupt status alias reg in global address map | ||
201 | * located at address 0x0024 | ||
202 | * Defined earlier (INTERRUPT_t) | ||
203 | */ | ||
204 | |||
205 | /* | ||
206 | * structure for software reset reg in global address map | ||
207 | * located at address 0x0028 | ||
208 | */ | ||
209 | typedef union _SW_RESET_t { | ||
210 | u32 value; | ||
211 | struct { | ||
212 | #ifdef _BIT_FIELDS_HTOL | ||
213 | u32 selfclr_disable:1; // bit 31 | ||
214 | u32 unused:24; // bits 7-30 | ||
215 | u32 mmc_sw_reset:1; // bit 6 | ||
216 | u32 mac_stat_sw_reset:1; // bit 5 | ||
217 | u32 mac_sw_reset:1; // bit 4 | ||
218 | u32 rxmac_sw_reset:1; // bit 3 | ||
219 | u32 txmac_sw_reset:1; // bit 2 | ||
220 | u32 rxdma_sw_reset:1; // bit 1 | ||
221 | u32 txdma_sw_reset:1; // bit 0 | ||
222 | #else | ||
223 | u32 txdma_sw_reset:1; // bit 0 | ||
224 | u32 rxdma_sw_reset:1; // bit 1 | ||
225 | u32 txmac_sw_reset:1; // bit 2 | ||
226 | u32 rxmac_sw_reset:1; // bit 3 | ||
227 | u32 mac_sw_reset:1; // bit 4 | ||
228 | u32 mac_stat_sw_reset:1; // bit 5 | ||
229 | u32 mmc_sw_reset:1; // bit 6 | ||
230 | u32 unused:24; // bits 7-30 | ||
231 | u32 selfclr_disable:1; // bit 31 | ||
232 | #endif | ||
233 | } bits; | ||
234 | } SW_RESET_t, *PSW_RESET_t; | ||
235 | |||
236 | /* | ||
237 | * structure for SLV Timer reg in global address map | ||
238 | * located at address 0x002C | ||
239 | */ | ||
240 | typedef union _SLV_TIMER_t { | ||
241 | u32 value; | ||
242 | struct { | ||
243 | #ifdef _BIT_FIELDS_HTOL | ||
244 | u32 unused:8; // bits 24-31 | ||
245 | u32 timer_ini:24; // bits 0-23 | ||
246 | #else | ||
247 | u32 timer_ini:24; // bits 0-23 | ||
248 | u32 unused:8; // bits 24-31 | ||
249 | #endif | ||
250 | } bits; | ||
251 | } SLV_TIMER_t, *PSLV_TIMER_t; | ||
252 | |||
253 | /* | ||
254 | * structure for MSI Configuration reg in global address map | ||
255 | * located at address 0x0030 | ||
256 | */ | ||
257 | typedef union _MSI_CONFIG_t { | ||
258 | u32 value; | ||
259 | struct { | ||
260 | #ifdef _BIT_FIELDS_HTOL | ||
261 | u32 unused1:13; // bits 19-31 | ||
262 | u32 msi_tc:3; // bits 16-18 | ||
263 | u32 unused2:11; // bits 5-15 | ||
264 | u32 msi_vector:5; // bits 0-4 | ||
265 | #else | ||
266 | u32 msi_vector:5; // bits 0-4 | ||
267 | u32 unused2:11; // bits 5-15 | ||
268 | u32 msi_tc:3; // bits 16-18 | ||
269 | u32 unused1:13; // bits 19-31 | ||
270 | #endif | ||
271 | } bits; | ||
272 | } MSI_CONFIG_t, *PMSI_CONFIG_t; | ||
273 | |||
274 | /* | ||
275 | * structure for Loopback reg in global address map | ||
276 | * located at address 0x0034 | ||
277 | */ | ||
278 | typedef union _LOOPBACK_t { | ||
279 | u32 value; | ||
280 | struct { | ||
281 | #ifdef _BIT_FIELDS_HTOL | ||
282 | u32 unused:30; // bits 2-31 | ||
283 | u32 dma_loopback:1; // bit 1 | ||
284 | u32 mac_loopback:1; // bit 0 | ||
285 | #else | ||
286 | u32 mac_loopback:1; // bit 0 | ||
287 | u32 dma_loopback:1; // bit 1 | ||
288 | u32 unused:30; // bits 2-31 | ||
289 | #endif | ||
290 | } bits; | ||
291 | } LOOPBACK_t, *PLOOPBACK_t; | ||
292 | |||
293 | /* | ||
294 | * GLOBAL Module of JAGCore Address Mapping | ||
295 | * Located at address 0x0000 | ||
296 | */ | ||
297 | typedef struct _GLOBAL_t { // Location: | ||
298 | Q_ADDR_t txq_start_addr; // 0x0000 | ||
299 | Q_ADDR_t txq_end_addr; // 0x0004 | ||
300 | Q_ADDR_t rxq_start_addr; // 0x0008 | ||
301 | Q_ADDR_t rxq_end_addr; // 0x000C | ||
302 | PM_CSR_t pm_csr; // 0x0010 | ||
303 | u32 unused; // 0x0014 | ||
304 | INTERRUPT_t int_status; // 0x0018 | ||
305 | INTERRUPT_t int_mask; // 0x001C | ||
306 | INTERRUPT_t int_alias_clr_en; // 0x0020 | ||
307 | INTERRUPT_t int_status_alias; // 0x0024 | ||
308 | SW_RESET_t sw_reset; // 0x0028 | ||
309 | SLV_TIMER_t slv_timer; // 0x002C | ||
310 | MSI_CONFIG_t msi_config; // 0x0030 | ||
311 | LOOPBACK_t loopback; // 0x0034 | ||
312 | u32 watchdog_timer; // 0x0038 | ||
313 | } GLOBAL_t, *PGLOBAL_t; | ||
314 | |||
315 | /* END OF GLOBAL REGISTER ADDRESS MAP */ | ||
316 | |||
317 | |||
318 | /* START OF TXDMA REGISTER ADDRESS MAP */ | ||
319 | |||
320 | /* | ||
321 | * structure for txdma control status reg in txdma address map | ||
322 | * located at address 0x1000 | ||
323 | */ | ||
324 | typedef union _TXDMA_CSR_t { | ||
325 | u32 value; | ||
326 | struct { | ||
327 | #ifdef _BIT_FIELDS_HTOL | ||
328 | u32 unused2:19; // bits 13-31 | ||
329 | u32 traffic_class:4; // bits 9-12 | ||
330 | u32 sngl_epkt_mode:1; // bit 8 | ||
331 | u32 cache_thrshld:4; // bits 4-7 | ||
332 | u32 unused1:2; // bits 2-3 | ||
333 | u32 drop_TLP_disable:1; // bit 1 | ||
334 | u32 halt:1; // bit 0 | ||
335 | #else | ||
336 | u32 halt:1; // bit 0 | ||
337 | u32 drop_TLP_disable:1; // bit 1 | ||
338 | u32 unused1:2; // bits 2-3 | ||
339 | u32 cache_thrshld:4; // bits 4-7 | ||
340 | u32 sngl_epkt_mode:1; // bit 8 | ||
341 | u32 traffic_class:4; // bits 9-12 | ||
342 | u32 unused2:19; // bits 13-31 | ||
343 | #endif | ||
344 | } bits; | ||
345 | } TXDMA_CSR_t, *PTXDMA_CSR_t; | ||
346 | |||
347 | /* | ||
348 | * structure for txdma packet ring base address hi reg in txdma address map | ||
349 | * located at address 0x1004 | ||
350 | * Defined earlier (u32) | ||
351 | */ | ||
352 | |||
353 | /* | ||
354 | * structure for txdma packet ring base address low reg in txdma address map | ||
355 | * located at address 0x1008 | ||
356 | * Defined earlier (u32) | ||
357 | */ | ||
358 | |||
359 | /* | ||
360 | * structure for txdma packet ring number of descriptor reg in txdma address | ||
361 | * map. Located at address 0x100C | ||
362 | */ | ||
363 | typedef union _TXDMA_PR_NUM_DES_t { | ||
364 | u32 value; | ||
365 | struct { | ||
366 | #ifdef _BIT_FIELDS_HTOL | ||
367 | u32 unused:22; // bits 10-31 | ||
368 | u32 pr_ndes:10; // bits 0-9 | ||
369 | #else | ||
370 | u32 pr_ndes:10; // bits 0-9 | ||
371 | u32 unused:22; // bits 10-31 | ||
372 | #endif | ||
373 | } bits; | ||
374 | } TXDMA_PR_NUM_DES_t, *PTXDMA_PR_NUM_DES_t; | ||
375 | |||
376 | |||
377 | typedef union _DMA10W_t { | ||
378 | u32 value; | ||
379 | struct { | ||
380 | #ifdef _BIT_FIELDS_HTOL | ||
381 | u32 unused:21; // bits 11-31 | ||
382 | u32 wrap:1; // bit 10 | ||
383 | u32 val:10; // bits 0-9 | ||
384 | #else | ||
385 | u32 val:10; // bits 0-9 | ||
386 | u32 wrap:1; // bit 10 | ||
387 | u32 unused:21; // bits 11-31 | ||
388 | #endif | ||
389 | } bits; | ||
390 | } DMA10W_t, *PDMA10W_t; | ||
391 | |||
392 | /* | ||
393 | * structure for txdma tx queue write address reg in txdma address map | ||
394 | * located at address 0x1010 | ||
395 | * Defined earlier (DMA10W_t) | ||
396 | */ | ||
397 | |||
398 | /* | ||
399 | * structure for txdma tx queue write address external reg in txdma address map | ||
400 | * located at address 0x1014 | ||
401 | * Defined earlier (DMA10W_t) | ||
402 | */ | ||
403 | |||
404 | /* | ||
405 | * structure for txdma tx queue read address reg in txdma address map | ||
406 | * located at address 0x1018 | ||
407 | * Defined earlier (DMA10W_t) | ||
408 | */ | ||
409 | |||
410 | /* | ||
411 | * structure for txdma status writeback address hi reg in txdma address map | ||
412 | * located at address 0x101C | ||
413 | * Defined earlier (u32) | ||
414 | */ | ||
415 | |||
416 | /* | ||
417 | * structure for txdma status writeback address lo reg in txdma address map | ||
418 | * located at address 0x1020 | ||
419 | * Defined earlier (u32) | ||
420 | */ | ||
421 | |||
422 | /* | ||
423 | * structure for txdma service request reg in txdma address map | ||
424 | * located at address 0x1024 | ||
425 | * Defined earlier (DMA10W_t) | ||
426 | */ | ||
427 | |||
428 | /* | ||
429 | * structure for txdma service complete reg in txdma address map | ||
430 | * located at address 0x1028 | ||
431 | * Defined earlier (DMA10W_t) | ||
432 | */ | ||
433 | |||
434 | typedef union _DMA4W_t { | ||
435 | u32 value; | ||
436 | struct { | ||
437 | #ifdef _BIT_FIELDS_HTOL | ||
438 | u32 unused:27; // bits 5-31 | ||
439 | u32 wrap:1; // bit 4 | ||
440 | u32 val:4; // bit 0-3 | ||
441 | #else | ||
442 | u32 val:4; // bits 0-3 | ||
443 | u32 wrap:1; // bit 4 | ||
444 | u32 unused:27; // bits 5-31 | ||
445 | #endif | ||
446 | } bits; | ||
447 | } DMA4W_t, *PDMA4W_t; | ||
448 | |||
449 | /* | ||
450 | * structure for txdma tx descriptor cache read index reg in txdma address map | ||
451 | * located at address 0x102C | ||
452 | * Defined earlier (DMA4W_t) | ||
453 | */ | ||
454 | |||
455 | /* | ||
456 | * structure for txdma tx descriptor cache write index reg in txdma address map | ||
457 | * located at address 0x1030 | ||
458 | * Defined earlier (DMA4W_t) | ||
459 | */ | ||
460 | |||
461 | /* | ||
462 | * structure for txdma error reg in txdma address map | ||
463 | * located at address 0x1034 | ||
464 | */ | ||
465 | typedef union _TXDMA_ERROR_t { | ||
466 | u32 value; | ||
467 | struct { | ||
468 | #ifdef _BIT_FIELDS_HTOL | ||
469 | u32 unused3:22; // bits 10-31 | ||
470 | u32 WrbkRewind:1; // bit 9 | ||
471 | u32 WrbkResend:1; // bit 8 | ||
472 | u32 unused2:2; // bits 6-7 | ||
473 | u32 DescrRewind:1; // bit 5 | ||
474 | u32 DescrResend:1; // bit 4 | ||
475 | u32 unused1:2; // bits 2-3 | ||
476 | u32 PyldRewind:1; // bit 1 | ||
477 | u32 PyldResend:1; // bit 0 | ||
478 | #else | ||
479 | u32 PyldResend:1; // bit 0 | ||
480 | u32 PyldRewind:1; // bit 1 | ||
481 | u32 unused1:2; // bits 2-3 | ||
482 | u32 DescrResend:1; // bit 4 | ||
483 | u32 DescrRewind:1; // bit 5 | ||
484 | u32 unused2:2; // bits 6-7 | ||
485 | u32 WrbkResend:1; // bit 8 | ||
486 | u32 WrbkRewind:1; // bit 9 | ||
487 | u32 unused3:22; // bits 10-31 | ||
488 | #endif | ||
489 | } bits; | ||
490 | } TXDMA_ERROR_t, *PTXDMA_ERROR_t; | ||
491 | |||
492 | /* | ||
493 | * Tx DMA Module of JAGCore Address Mapping | ||
494 | * Located at address 0x1000 | ||
495 | */ | ||
496 | typedef struct _TXDMA_t { // Location: | ||
497 | TXDMA_CSR_t csr; // 0x1000 | ||
498 | u32 pr_base_hi; // 0x1004 | ||
499 | u32 pr_base_lo; // 0x1008 | ||
500 | TXDMA_PR_NUM_DES_t pr_num_des; // 0x100C | ||
501 | DMA10W_t txq_wr_addr; // 0x1010 | ||
502 | DMA10W_t txq_wr_addr_ext; // 0x1014 | ||
503 | DMA10W_t txq_rd_addr; // 0x1018 | ||
504 | u32 dma_wb_base_hi; // 0x101C | ||
505 | u32 dma_wb_base_lo; // 0x1020 | ||
506 | DMA10W_t service_request; // 0x1024 | ||
507 | DMA10W_t service_complete; // 0x1028 | ||
508 | DMA4W_t cache_rd_index; // 0x102C | ||
509 | DMA4W_t cache_wr_index; // 0x1030 | ||
510 | TXDMA_ERROR_t TxDmaError; // 0x1034 | ||
511 | u32 DescAbortCount; // 0x1038 | ||
512 | u32 PayloadAbortCnt; // 0x103c | ||
513 | u32 WriteBackAbortCnt; // 0x1040 | ||
514 | u32 DescTimeoutCnt; // 0x1044 | ||
515 | u32 PayloadTimeoutCnt; // 0x1048 | ||
516 | u32 WriteBackTimeoutCnt; // 0x104c | ||
517 | u32 DescErrorCount; // 0x1050 | ||
518 | u32 PayloadErrorCnt; // 0x1054 | ||
519 | u32 WriteBackErrorCnt; // 0x1058 | ||
520 | u32 DroppedTLPCount; // 0x105c | ||
521 | DMA10W_t NewServiceComplete; // 0x1060 | ||
522 | u32 EthernetPacketCount; // 0x1064 | ||
523 | } TXDMA_t, *PTXDMA_t; | ||
524 | |||
525 | /* END OF TXDMA REGISTER ADDRESS MAP */ | ||
526 | |||
527 | |||
528 | /* START OF RXDMA REGISTER ADDRESS MAP */ | ||
529 | |||
530 | /* | ||
531 | * structure for control status reg in rxdma address map | ||
532 | * Located at address 0x2000 | ||
533 | */ | ||
534 | typedef union _RXDMA_CSR_t { | ||
535 | u32 value; | ||
536 | struct { | ||
537 | #ifdef _BIT_FIELDS_HTOL | ||
538 | u32 unused2:14; // bits 18-31 | ||
539 | u32 halt_status:1; // bit 17 | ||
540 | u32 pkt_done_flush:1; // bit 16 | ||
541 | u32 pkt_drop_disable:1; // bit 15 | ||
542 | u32 unused1:1; // bit 14 | ||
543 | u32 fbr1_enable:1; // bit 13 | ||
544 | u32 fbr1_size:2; // bits 11-12 | ||
545 | u32 fbr0_enable:1; // bit 10 | ||
546 | u32 fbr0_size:2; // bits 8-9 | ||
547 | u32 dma_big_endian:1; // bit 7 | ||
548 | u32 pkt_big_endian:1; // bit 6 | ||
549 | u32 psr_big_endian:1; // bit 5 | ||
550 | u32 fbr_big_endian:1; // bit 4 | ||
551 | u32 tc:3; // bits 1-3 | ||
552 | u32 halt:1; // bit 0 | ||
553 | #else | ||
554 | u32 halt:1; // bit 0 | ||
555 | u32 tc:3; // bits 1-3 | ||
556 | u32 fbr_big_endian:1; // bit 4 | ||
557 | u32 psr_big_endian:1; // bit 5 | ||
558 | u32 pkt_big_endian:1; // bit 6 | ||
559 | u32 dma_big_endian:1; // bit 7 | ||
560 | u32 fbr0_size:2; // bits 8-9 | ||
561 | u32 fbr0_enable:1; // bit 10 | ||
562 | u32 fbr1_size:2; // bits 11-12 | ||
563 | u32 fbr1_enable:1; // bit 13 | ||
564 | u32 unused1:1; // bit 14 | ||
565 | u32 pkt_drop_disable:1; // bit 15 | ||
566 | u32 pkt_done_flush:1; // bit 16 | ||
567 | u32 halt_status:1; // bit 17 | ||
568 | u32 unused2:14; // bits 18-31 | ||
569 | #endif | ||
570 | } bits; | ||
571 | } RXDMA_CSR_t, *PRXDMA_CSR_t; | ||
572 | |||
573 | /* | ||
574 | * structure for dma writeback lo reg in rxdma address map | ||
575 | * located at address 0x2004 | ||
576 | * Defined earlier (u32) | ||
577 | */ | ||
578 | |||
579 | /* | ||
580 | * structure for dma writeback hi reg in rxdma address map | ||
581 | * located at address 0x2008 | ||
582 | * Defined earlier (u32) | ||
583 | */ | ||
584 | |||
585 | /* | ||
586 | * structure for number of packets done reg in rxdma address map | ||
587 | * located at address 0x200C | ||
588 | */ | ||
589 | typedef union _RXDMA_NUM_PKT_DONE_t { | ||
590 | u32 value; | ||
591 | struct { | ||
592 | #ifdef _BIT_FIELDS_HTOL | ||
593 | u32 unused:24; // bits 8-31 | ||
594 | u32 num_done:8; // bits 0-7 | ||
595 | #else | ||
596 | u32 num_done:8; // bits 0-7 | ||
597 | u32 unused:24; // bits 8-31 | ||
598 | #endif | ||
599 | } bits; | ||
600 | } RXDMA_NUM_PKT_DONE_t, *PRXDMA_NUM_PKT_DONE_t; | ||
601 | |||
602 | /* | ||
603 | * structure for max packet time reg in rxdma address map | ||
604 | * located at address 0x2010 | ||
605 | */ | ||
606 | typedef union _RXDMA_MAX_PKT_TIME_t { | ||
607 | u32 value; | ||
608 | struct { | ||
609 | #ifdef _BIT_FIELDS_HTOL | ||
610 | u32 unused:14; // bits 18-31 | ||
611 | u32 time_done:18; // bits 0-17 | ||
612 | #else | ||
613 | u32 time_done:18; // bits 0-17 | ||
614 | u32 unused:14; // bits 18-31 | ||
615 | #endif | ||
616 | } bits; | ||
617 | } RXDMA_MAX_PKT_TIME_t, *PRXDMA_MAX_PKT_TIME_t; | ||
618 | |||
619 | /* | ||
620 | * structure for rx queue read address reg in rxdma address map | ||
621 | * located at address 0x2014 | ||
622 | * Defined earlier (DMA10W_t) | ||
623 | */ | ||
624 | |||
625 | /* | ||
626 | * structure for rx queue read address external reg in rxdma address map | ||
627 | * located at address 0x2018 | ||
628 | * Defined earlier (DMA10W_t) | ||
629 | */ | ||
630 | |||
631 | /* | ||
632 | * structure for rx queue write address reg in rxdma address map | ||
633 | * located at address 0x201C | ||
634 | * Defined earlier (DMA10W_t) | ||
635 | */ | ||
636 | |||
637 | /* | ||
638 | * structure for packet status ring base address lo reg in rxdma address map | ||
639 | * located at address 0x2020 | ||
640 | * Defined earlier (u32) | ||
641 | */ | ||
642 | |||
643 | /* | ||
644 | * structure for packet status ring base address hi reg in rxdma address map | ||
645 | * located at address 0x2024 | ||
646 | * Defined earlier (u32) | ||
647 | */ | ||
648 | |||
649 | /* | ||
650 | * structure for packet status ring number of descriptors reg in rxdma address | ||
651 | * map. Located at address 0x2028 | ||
652 | */ | ||
653 | typedef union _RXDMA_PSR_NUM_DES_t { | ||
654 | u32 value; | ||
655 | struct { | ||
656 | #ifdef _BIT_FIELDS_HTOL | ||
657 | u32 unused:20; // bits 12-31 | ||
658 | u32 psr_ndes:12; // bit 0-11 | ||
659 | #else | ||
660 | u32 psr_ndes:12; // bit 0-11 | ||
661 | u32 unused:20; // bits 12-31 | ||
662 | #endif | ||
663 | } bits; | ||
664 | } RXDMA_PSR_NUM_DES_t, *PRXDMA_PSR_NUM_DES_t; | ||
665 | |||
666 | /* | ||
667 | * structure for packet status ring available offset reg in rxdma address map | ||
668 | * located at address 0x202C | ||
669 | */ | ||
670 | typedef union _RXDMA_PSR_AVAIL_OFFSET_t { | ||
671 | u32 value; | ||
672 | struct { | ||
673 | #ifdef _BIT_FIELDS_HTOL | ||
674 | u32 unused:19; // bits 13-31 | ||
675 | u32 psr_avail_wrap:1; // bit 12 | ||
676 | u32 psr_avail:12; // bit 0-11 | ||
677 | #else | ||
678 | u32 psr_avail:12; // bit 0-11 | ||
679 | u32 psr_avail_wrap:1; // bit 12 | ||
680 | u32 unused:19; // bits 13-31 | ||
681 | #endif | ||
682 | } bits; | ||
683 | } RXDMA_PSR_AVAIL_OFFSET_t, *PRXDMA_PSR_AVAIL_OFFSET_t; | ||
684 | |||
685 | /* | ||
686 | * structure for packet status ring full offset reg in rxdma address map | ||
687 | * located at address 0x2030 | ||
688 | */ | ||
689 | typedef union _RXDMA_PSR_FULL_OFFSET_t { | ||
690 | u32 value; | ||
691 | struct { | ||
692 | #ifdef _BIT_FIELDS_HTOL | ||
693 | u32 unused:19; // bits 13-31 | ||
694 | u32 psr_full_wrap:1; // bit 12 | ||
695 | u32 psr_full:12; // bit 0-11 | ||
696 | #else | ||
697 | u32 psr_full:12; // bit 0-11 | ||
698 | u32 psr_full_wrap:1; // bit 12 | ||
699 | u32 unused:19; // bits 13-31 | ||
700 | #endif | ||
701 | } bits; | ||
702 | } RXDMA_PSR_FULL_OFFSET_t, *PRXDMA_PSR_FULL_OFFSET_t; | ||
703 | |||
704 | /* | ||
705 | * structure for packet status ring access index reg in rxdma address map | ||
706 | * located at address 0x2034 | ||
707 | */ | ||
708 | typedef union _RXDMA_PSR_ACCESS_INDEX_t { | ||
709 | u32 value; | ||
710 | struct { | ||
711 | #ifdef _BIT_FIELDS_HTOL | ||
712 | u32 unused:27; // bits 5-31 | ||
713 | u32 psr_ai:5; // bits 0-4 | ||
714 | #else | ||
715 | u32 psr_ai:5; // bits 0-4 | ||
716 | u32 unused:27; // bits 5-31 | ||
717 | #endif | ||
718 | } bits; | ||
719 | } RXDMA_PSR_ACCESS_INDEX_t, *PRXDMA_PSR_ACCESS_INDEX_t; | ||
720 | |||
721 | /* | ||
722 | * structure for packet status ring minimum descriptors reg in rxdma address | ||
723 | * map. Located at address 0x2038 | ||
724 | */ | ||
725 | typedef union _RXDMA_PSR_MIN_DES_t { | ||
726 | u32 value; | ||
727 | struct { | ||
728 | #ifdef _BIT_FIELDS_HTOL | ||
729 | u32 unused:20; // bits 12-31 | ||
730 | u32 psr_min:12; // bits 0-11 | ||
731 | #else | ||
732 | u32 psr_min:12; // bits 0-11 | ||
733 | u32 unused:20; // bits 12-31 | ||
734 | #endif | ||
735 | } bits; | ||
736 | } RXDMA_PSR_MIN_DES_t, *PRXDMA_PSR_MIN_DES_t; | ||
737 | |||
738 | /* | ||
739 | * structure for free buffer ring base lo address reg in rxdma address map | ||
740 | * located at address 0x203C | ||
741 | * Defined earlier (u32) | ||
742 | */ | ||
743 | |||
744 | /* | ||
745 | * structure for free buffer ring base hi address reg in rxdma address map | ||
746 | * located at address 0x2040 | ||
747 | * Defined earlier (u32) | ||
748 | */ | ||
749 | |||
750 | /* | ||
751 | * structure for free buffer ring number of descriptors reg in rxdma address | ||
752 | * map. Located at address 0x2044 | ||
753 | */ | ||
754 | typedef union _RXDMA_FBR_NUM_DES_t { | ||
755 | u32 value; | ||
756 | struct { | ||
757 | #ifdef _BIT_FIELDS_HTOL | ||
758 | u32 unused:22; // bits 10-31 | ||
759 | u32 fbr_ndesc:10; // bits 0-9 | ||
760 | #else | ||
761 | u32 fbr_ndesc:10; // bits 0-9 | ||
762 | u32 unused:22; // bits 10-31 | ||
763 | #endif | ||
764 | } bits; | ||
765 | } RXDMA_FBR_NUM_DES_t, *PRXDMA_FBR_NUM_DES_t; | ||
766 | |||
767 | /* | ||
768 | * structure for free buffer ring 0 available offset reg in rxdma address map | ||
769 | * located at address 0x2048 | ||
770 | * Defined earlier (DMA10W_t) | ||
771 | */ | ||
772 | |||
773 | /* | ||
774 | * structure for free buffer ring 0 full offset reg in rxdma address map | ||
775 | * located at address 0x204C | ||
776 | * Defined earlier (DMA10W_t) | ||
777 | */ | ||
778 | |||
779 | /* | ||
780 | * structure for free buffer cache 0 full offset reg in rxdma address map | ||
781 | * located at address 0x2050 | ||
782 | */ | ||
783 | typedef union _RXDMA_FBC_RD_INDEX_t { | ||
784 | u32 value; | ||
785 | struct { | ||
786 | #ifdef _BIT_FIELDS_HTOL | ||
787 | u32 unused:27; // bits 5-31 | ||
788 | u32 fbc_rdi:5; // bit 0-4 | ||
789 | #else | ||
790 | u32 fbc_rdi:5; // bit 0-4 | ||
791 | u32 unused:27; // bits 5-31 | ||
792 | #endif | ||
793 | } bits; | ||
794 | } RXDMA_FBC_RD_INDEX_t, *PRXDMA_FBC_RD_INDEX_t; | ||
795 | |||
796 | /* | ||
797 | * structure for free buffer ring 0 minimum descriptor reg in rxdma address map | ||
798 | * located at address 0x2054 | ||
799 | */ | ||
800 | typedef union _RXDMA_FBR_MIN_DES_t { | ||
801 | u32 value; | ||
802 | struct { | ||
803 | #ifdef _BIT_FIELDS_HTOL | ||
804 | u32 unused:22; // bits 10-31 | ||
805 | u32 fbr_min:10; // bits 0-9 | ||
806 | #else | ||
807 | u32 fbr_min:10; // bits 0-9 | ||
808 | u32 unused:22; // bits 10-31 | ||
809 | #endif | ||
810 | } bits; | ||
811 | } RXDMA_FBR_MIN_DES_t, *PRXDMA_FBR_MIN_DES_t; | ||
812 | |||
813 | /* | ||
814 | * structure for free buffer ring 1 base address lo reg in rxdma address map | ||
815 | * located at address 0x2058 - 0x205C | ||
816 | * Defined earlier (RXDMA_FBR_BASE_LO_t and RXDMA_FBR_BASE_HI_t) | ||
817 | */ | ||
818 | |||
819 | /* | ||
820 | * structure for free buffer ring 1 number of descriptors reg in rxdma address | ||
821 | * map. Located at address 0x2060 | ||
822 | * Defined earlier (RXDMA_FBR_NUM_DES_t) | ||
823 | */ | ||
824 | |||
825 | /* | ||
826 | * structure for free buffer ring 1 available offset reg in rxdma address map | ||
827 | * located at address 0x2064 | ||
828 | * Defined Earlier (RXDMA_FBR_AVAIL_OFFSET_t) | ||
829 | */ | ||
830 | |||
831 | /* | ||
832 | * structure for free buffer ring 1 full offset reg in rxdma address map | ||
833 | * located at address 0x2068 | ||
834 | * Defined Earlier (RXDMA_FBR_FULL_OFFSET_t) | ||
835 | */ | ||
836 | |||
837 | /* | ||
838 | * structure for free buffer cache 1 read index reg in rxdma address map | ||
839 | * located at address 0x206C | ||
840 | * Defined Earlier (RXDMA_FBC_RD_INDEX_t) | ||
841 | */ | ||
842 | |||
843 | /* | ||
844 | * structure for free buffer ring 1 minimum descriptor reg in rxdma address map | ||
845 | * located at address 0x2070 | ||
846 | * Defined Earlier (RXDMA_FBR_MIN_DES_t) | ||
847 | */ | ||
848 | |||
849 | /* | ||
850 | * Rx DMA Module of JAGCore Address Mapping | ||
851 | * Located at address 0x2000 | ||
852 | */ | ||
853 | typedef struct _RXDMA_t { // Location: | ||
854 | RXDMA_CSR_t csr; // 0x2000 | ||
855 | u32 dma_wb_base_lo; // 0x2004 | ||
856 | u32 dma_wb_base_hi; // 0x2008 | ||
857 | RXDMA_NUM_PKT_DONE_t num_pkt_done; // 0x200C | ||
858 | RXDMA_MAX_PKT_TIME_t max_pkt_time; // 0x2010 | ||
859 | DMA10W_t rxq_rd_addr; // 0x2014 | ||
860 | DMA10W_t rxq_rd_addr_ext; // 0x2018 | ||
861 | DMA10W_t rxq_wr_addr; // 0x201C | ||
862 | u32 psr_base_lo; // 0x2020 | ||
863 | u32 psr_base_hi; // 0x2024 | ||
864 | RXDMA_PSR_NUM_DES_t psr_num_des; // 0x2028 | ||
865 | RXDMA_PSR_AVAIL_OFFSET_t psr_avail_offset; // 0x202C | ||
866 | RXDMA_PSR_FULL_OFFSET_t psr_full_offset; // 0x2030 | ||
867 | RXDMA_PSR_ACCESS_INDEX_t psr_access_index; // 0x2034 | ||
868 | RXDMA_PSR_MIN_DES_t psr_min_des; // 0x2038 | ||
869 | u32 fbr0_base_lo; // 0x203C | ||
870 | u32 fbr0_base_hi; // 0x2040 | ||
871 | RXDMA_FBR_NUM_DES_t fbr0_num_des; // 0x2044 | ||
872 | DMA10W_t fbr0_avail_offset; // 0x2048 | ||
873 | DMA10W_t fbr0_full_offset; // 0x204C | ||
874 | RXDMA_FBC_RD_INDEX_t fbr0_rd_index; // 0x2050 | ||
875 | RXDMA_FBR_MIN_DES_t fbr0_min_des; // 0x2054 | ||
876 | u32 fbr1_base_lo; // 0x2058 | ||
877 | u32 fbr1_base_hi; // 0x205C | ||
878 | RXDMA_FBR_NUM_DES_t fbr1_num_des; // 0x2060 | ||
879 | DMA10W_t fbr1_avail_offset; // 0x2064 | ||
880 | DMA10W_t fbr1_full_offset; // 0x2068 | ||
881 | RXDMA_FBC_RD_INDEX_t fbr1_rd_index; // 0x206C | ||
882 | RXDMA_FBR_MIN_DES_t fbr1_min_des; // 0x2070 | ||
883 | } RXDMA_t, *PRXDMA_t; | ||
884 | |||
885 | /* END OF RXDMA REGISTER ADDRESS MAP */ | ||
886 | |||
887 | |||
888 | /* START OF TXMAC REGISTER ADDRESS MAP */ | ||
889 | |||
890 | /* | ||
891 | * structure for control reg in txmac address map | ||
892 | * located at address 0x3000 | ||
893 | */ | ||
894 | typedef union _TXMAC_CTL_t { | ||
895 | u32 value; | ||
896 | struct { | ||
897 | #ifdef _BIT_FIELDS_HTOL | ||
898 | u32 unused:24; // bits 8-31 | ||
899 | u32 cklseg_diable:1; // bit 7 | ||
900 | u32 ckbcnt_disable:1; // bit 6 | ||
901 | u32 cksegnum:1; // bit 5 | ||
902 | u32 async_disable:1; // bit 4 | ||
903 | u32 fc_disable:1; // bit 3 | ||
904 | u32 mcif_disable:1; // bit 2 | ||
905 | u32 mif_disable:1; // bit 1 | ||
906 | u32 txmac_en:1; // bit 0 | ||
907 | #else | ||
908 | u32 txmac_en:1; // bit 0 | ||
909 | u32 mif_disable:1; // bit 1 mac interface | ||
910 | u32 mcif_disable:1; // bit 2 mem. contr. interface | ||
911 | u32 fc_disable:1; // bit 3 | ||
912 | u32 async_disable:1; // bit 4 | ||
913 | u32 cksegnum:1; // bit 5 | ||
914 | u32 ckbcnt_disable:1; // bit 6 | ||
915 | u32 cklseg_diable:1; // bit 7 | ||
916 | u32 unused:24; // bits 8-31 | ||
917 | #endif | ||
918 | } bits; | ||
919 | } TXMAC_CTL_t, *PTXMAC_CTL_t; | ||
920 | |||
921 | /* | ||
922 | * structure for shadow pointer reg in txmac address map | ||
923 | * located at address 0x3004 | ||
924 | */ | ||
925 | typedef union _TXMAC_SHADOW_PTR_t { | ||
926 | u32 value; | ||
927 | struct { | ||
928 | #ifdef _BIT_FIELDS_HTOL | ||
929 | u32 reserved2:5; // bits 27-31 | ||
930 | u32 txq_rd_ptr:11; // bits 16-26 | ||
931 | u32 reserved:5; // bits 11-15 | ||
932 | u32 txq_wr_ptr:11; // bits 0-10 | ||
933 | #else | ||
934 | u32 txq_wr_ptr:11; // bits 0-10 | ||
935 | u32 reserved:5; // bits 11-15 | ||
936 | u32 txq_rd_ptr:11; // bits 16-26 | ||
937 | u32 reserved2:5; // bits 27-31 | ||
938 | #endif | ||
939 | } bits; | ||
940 | } TXMAC_SHADOW_PTR_t, *PTXMAC_SHADOW_PTR_t; | ||
941 | |||
942 | /* | ||
943 | * structure for error count reg in txmac address map | ||
944 | * located at address 0x3008 | ||
945 | */ | ||
946 | typedef union _TXMAC_ERR_CNT_t { | ||
947 | u32 value; | ||
948 | struct { | ||
949 | #ifdef _BIT_FIELDS_HTOL | ||
950 | u32 unused:20; // bits 12-31 | ||
951 | u32 reserved:4; // bits 8-11 | ||
952 | u32 txq_underrun:4; // bits 4-7 | ||
953 | u32 fifo_underrun:4; // bits 0-3 | ||
954 | #else | ||
955 | u32 fifo_underrun:4; // bits 0-3 | ||
956 | u32 txq_underrun:4; // bits 4-7 | ||
957 | u32 reserved:4; // bits 8-11 | ||
958 | u32 unused:20; // bits 12-31 | ||
959 | #endif | ||
960 | } bits; | ||
961 | } TXMAC_ERR_CNT_t, *PTXMAC_ERR_CNT_t; | ||
962 | |||
963 | /* | ||
964 | * structure for max fill reg in txmac address map | ||
965 | * located at address 0x300C | ||
966 | */ | ||
967 | typedef union _TXMAC_MAX_FILL_t { | ||
968 | u32 value; | ||
969 | struct { | ||
970 | #ifdef _BIT_FIELDS_HTOL | ||
971 | u32 unused:20; // bits 12-31 | ||
972 | u32 max_fill:12; // bits 0-11 | ||
973 | #else | ||
974 | u32 max_fill:12; // bits 0-11 | ||
975 | u32 unused:20; // bits 12-31 | ||
976 | #endif | ||
977 | } bits; | ||
978 | } TXMAC_MAX_FILL_t, *PTXMAC_MAX_FILL_t; | ||
979 | |||
980 | /* | ||
981 | * structure for cf parameter reg in txmac address map | ||
982 | * located at address 0x3010 | ||
983 | */ | ||
984 | typedef union _TXMAC_CF_PARAM_t { | ||
985 | u32 value; | ||
986 | struct { | ||
987 | #ifdef _BIT_FIELDS_HTOL | ||
988 | u32 cfep:16; // bits 16-31 | ||
989 | u32 cfpt:16; // bits 0-15 | ||
990 | #else | ||
991 | u32 cfpt:16; // bits 0-15 | ||
992 | u32 cfep:16; // bits 16-31 | ||
993 | #endif | ||
994 | } bits; | ||
995 | } TXMAC_CF_PARAM_t, *PTXMAC_CF_PARAM_t; | ||
996 | |||
997 | /* | ||
998 | * structure for tx test reg in txmac address map | ||
999 | * located at address 0x3014 | ||
1000 | */ | ||
1001 | typedef union _TXMAC_TXTEST_t { | ||
1002 | u32 value; | ||
1003 | struct { | ||
1004 | #ifdef _BIT_FIELDS_HTOL | ||
1005 | u32 unused2:15; // bits 17-31 | ||
1006 | u32 reserved1:1; // bit 16 | ||
1007 | u32 txtest_en:1; // bit 15 | ||
1008 | u32 unused1:4; // bits 11-14 | ||
1009 | u32 txqtest_ptr:11; // bits 0-11 | ||
1010 | #else | ||
1011 | u32 txqtest_ptr:11; // bits 0-10 | ||
1012 | u32 unused1:4; // bits 11-14 | ||
1013 | u32 txtest_en:1; // bit 15 | ||
1014 | u32 reserved1:1; // bit 16 | ||
1015 | u32 unused2:15; // bits 17-31 | ||
1016 | #endif | ||
1017 | } bits; | ||
1018 | } TXMAC_TXTEST_t, *PTXMAC_TXTEST_t; | ||
1019 | |||
1020 | /* | ||
1021 | * structure for error reg in txmac address map | ||
1022 | * located at address 0x3018 | ||
1023 | */ | ||
1024 | typedef union _TXMAC_ERR_t { | ||
1025 | u32 value; | ||
1026 | struct { | ||
1027 | #ifdef _BIT_FIELDS_HTOL | ||
1028 | u32 unused2:23; // bits 9-31 | ||
1029 | u32 fifo_underrun:1; // bit 8 | ||
1030 | u32 unused1:2; // bits 6-7 | ||
1031 | u32 ctrl2_err:1; // bit 5 | ||
1032 | u32 txq_underrun:1; // bit 4 | ||
1033 | u32 bcnt_err:1; // bit 3 | ||
1034 | u32 lseg_err:1; // bit 2 | ||
1035 | u32 segnum_err:1; // bit 1 | ||
1036 | u32 seg0_err:1; // bit 0 | ||
1037 | #else | ||
1038 | u32 seg0_err:1; // bit 0 | ||
1039 | u32 segnum_err:1; // bit 1 | ||
1040 | u32 lseg_err:1; // bit 2 | ||
1041 | u32 bcnt_err:1; // bit 3 | ||
1042 | u32 txq_underrun:1; // bit 4 | ||
1043 | u32 ctrl2_err:1; // bit 5 | ||
1044 | u32 unused1:2; // bits 6-7 | ||
1045 | u32 fifo_underrun:1; // bit 8 | ||
1046 | u32 unused2:23; // bits 9-31 | ||
1047 | #endif | ||
1048 | } bits; | ||
1049 | } TXMAC_ERR_t, *PTXMAC_ERR_t; | ||
1050 | |||
1051 | /* | ||
1052 | * structure for error interrupt reg in txmac address map | ||
1053 | * located at address 0x301C | ||
1054 | */ | ||
1055 | typedef union _TXMAC_ERR_INT_t { | ||
1056 | u32 value; | ||
1057 | struct { | ||
1058 | #ifdef _BIT_FIELDS_HTOL | ||
1059 | u32 unused2:23; // bits 9-31 | ||
1060 | u32 fifo_underrun:1; // bit 8 | ||
1061 | u32 unused1:2; // bits 6-7 | ||
1062 | u32 ctrl2_err:1; // bit 5 | ||
1063 | u32 txq_underrun:1; // bit 4 | ||
1064 | u32 bcnt_err:1; // bit 3 | ||
1065 | u32 lseg_err:1; // bit 2 | ||
1066 | u32 segnum_err:1; // bit 1 | ||
1067 | u32 seg0_err:1; // bit 0 | ||
1068 | #else | ||
1069 | u32 seg0_err:1; // bit 0 | ||
1070 | u32 segnum_err:1; // bit 1 | ||
1071 | u32 lseg_err:1; // bit 2 | ||
1072 | u32 bcnt_err:1; // bit 3 | ||
1073 | u32 txq_underrun:1; // bit 4 | ||
1074 | u32 ctrl2_err:1; // bit 5 | ||
1075 | u32 unused1:2; // bits 6-7 | ||
1076 | u32 fifo_underrun:1; // bit 8 | ||
1077 | u32 unused2:23; // bits 9-31 | ||
1078 | #endif | ||
1079 | } bits; | ||
1080 | } TXMAC_ERR_INT_t, *PTXMAC_ERR_INT_t; | ||
1081 | |||
1082 | /* | ||
1083 | * structure for error interrupt reg in txmac address map | ||
1084 | * located at address 0x3020 | ||
1085 | */ | ||
1086 | typedef union _TXMAC_CP_CTRL_t { | ||
1087 | u32 value; | ||
1088 | struct { | ||
1089 | #ifdef _BIT_FIELDS_HTOL | ||
1090 | u32 unused:30; // bits 2-31 | ||
1091 | u32 bp_req:1; // bit 1 | ||
1092 | u32 bp_xonxoff:1; // bit 0 | ||
1093 | #else | ||
1094 | u32 bp_xonxoff:1; // bit 0 | ||
1095 | u32 bp_req:1; // bit 1 | ||
1096 | u32 unused:30; // bits 2-31 | ||
1097 | #endif | ||
1098 | } bits; | ||
1099 | } TXMAC_BP_CTRL_t, *PTXMAC_BP_CTRL_t; | ||
1100 | |||
1101 | /* | ||
1102 | * Tx MAC Module of JAGCore Address Mapping | ||
1103 | */ | ||
1104 | typedef struct _TXMAC_t { // Location: | ||
1105 | TXMAC_CTL_t ctl; // 0x3000 | ||
1106 | TXMAC_SHADOW_PTR_t shadow_ptr; // 0x3004 | ||
1107 | TXMAC_ERR_CNT_t err_cnt; // 0x3008 | ||
1108 | TXMAC_MAX_FILL_t max_fill; // 0x300C | ||
1109 | TXMAC_CF_PARAM_t cf_param; // 0x3010 | ||
1110 | TXMAC_TXTEST_t tx_test; // 0x3014 | ||
1111 | TXMAC_ERR_t err; // 0x3018 | ||
1112 | TXMAC_ERR_INT_t err_int; // 0x301C | ||
1113 | TXMAC_BP_CTRL_t bp_ctrl; // 0x3020 | ||
1114 | } TXMAC_t, *PTXMAC_t; | ||
1115 | |||
1116 | /* END OF TXMAC REGISTER ADDRESS MAP */ | ||
1117 | |||
1118 | /* START OF RXMAC REGISTER ADDRESS MAP */ | ||
1119 | |||
1120 | /* | ||
1121 | * structure for rxmac control reg in rxmac address map | ||
1122 | * located at address 0x4000 | ||
1123 | */ | ||
1124 | typedef union _RXMAC_CTRL_t { | ||
1125 | u32 value; | ||
1126 | struct { | ||
1127 | #ifdef _BIT_FIELDS_HTOL | ||
1128 | u32 reserved:25; // bits 7-31 | ||
1129 | u32 rxmac_int_disable:1; // bit 6 | ||
1130 | u32 async_disable:1; // bit 5 | ||
1131 | u32 mif_disable:1; // bit 4 | ||
1132 | u32 wol_disable:1; // bit 3 | ||
1133 | u32 pkt_filter_disable:1; // bit 2 | ||
1134 | u32 mcif_disable:1; // bit 1 | ||
1135 | u32 rxmac_en:1; // bit 0 | ||
1136 | #else | ||
1137 | u32 rxmac_en:1; // bit 0 | ||
1138 | u32 mcif_disable:1; // bit 1 | ||
1139 | u32 pkt_filter_disable:1; // bit 2 | ||
1140 | u32 wol_disable:1; // bit 3 | ||
1141 | u32 mif_disable:1; // bit 4 | ||
1142 | u32 async_disable:1; // bit 5 | ||
1143 | u32 rxmac_int_disable:1; // bit 6 | ||
1144 | u32 reserved:25; // bits 7-31 | ||
1145 | #endif | ||
1146 | } bits; | ||
1147 | } RXMAC_CTRL_t, *PRXMAC_CTRL_t; | ||
1148 | |||
1149 | /* | ||
1150 | * structure for Wake On Lan Control and CRC 0 reg in rxmac address map | ||
1151 | * located at address 0x4004 | ||
1152 | */ | ||
1153 | typedef union _RXMAC_WOL_CTL_CRC0_t { | ||
1154 | u32 value; | ||
1155 | struct { | ||
1156 | #ifdef _BIT_FIELDS_HTOL | ||
1157 | u32 crc0:16; // bits 16-31 | ||
1158 | u32 reserve:4; // bits 12-15 | ||
1159 | u32 ignore_pp:1; // bit 11 | ||
1160 | u32 ignore_mp:1; // bit 10 | ||
1161 | u32 clr_intr:1; // bit 9 | ||
1162 | u32 ignore_link_chg:1; // bit 8 | ||
1163 | u32 ignore_uni:1; // bit 7 | ||
1164 | u32 ignore_multi:1; // bit 6 | ||
1165 | u32 ignore_broad:1; // bit 5 | ||
1166 | u32 valid_crc4:1; // bit 4 | ||
1167 | u32 valid_crc3:1; // bit 3 | ||
1168 | u32 valid_crc2:1; // bit 2 | ||
1169 | u32 valid_crc1:1; // bit 1 | ||
1170 | u32 valid_crc0:1; // bit 0 | ||
1171 | #else | ||
1172 | u32 valid_crc0:1; // bit 0 | ||
1173 | u32 valid_crc1:1; // bit 1 | ||
1174 | u32 valid_crc2:1; // bit 2 | ||
1175 | u32 valid_crc3:1; // bit 3 | ||
1176 | u32 valid_crc4:1; // bit 4 | ||
1177 | u32 ignore_broad:1; // bit 5 | ||
1178 | u32 ignore_multi:1; // bit 6 | ||
1179 | u32 ignore_uni:1; // bit 7 | ||
1180 | u32 ignore_link_chg:1; // bit 8 | ||
1181 | u32 clr_intr:1; // bit 9 | ||
1182 | u32 ignore_mp:1; // bit 10 | ||
1183 | u32 ignore_pp:1; // bit 11 | ||
1184 | u32 reserve:4; // bits 12-15 | ||
1185 | u32 crc0:16; // bits 16-31 | ||
1186 | #endif | ||
1187 | } bits; | ||
1188 | } RXMAC_WOL_CTL_CRC0_t, *PRXMAC_WOL_CTL_CRC0_t; | ||
1189 | |||
1190 | /* | ||
1191 | * structure for CRC 1 and CRC 2 reg in rxmac address map | ||
1192 | * located at address 0x4008 | ||
1193 | */ | ||
1194 | typedef union _RXMAC_WOL_CRC12_t { | ||
1195 | u32 value; | ||
1196 | struct { | ||
1197 | #ifdef _BIT_FIELDS_HTOL | ||
1198 | u32 crc2:16; // bits 16-31 | ||
1199 | u32 crc1:16; // bits 0-15 | ||
1200 | #else | ||
1201 | u32 crc1:16; // bits 0-15 | ||
1202 | u32 crc2:16; // bits 16-31 | ||
1203 | #endif | ||
1204 | } bits; | ||
1205 | } RXMAC_WOL_CRC12_t, *PRXMAC_WOL_CRC12_t; | ||
1206 | |||
1207 | /* | ||
1208 | * structure for CRC 3 and CRC 4 reg in rxmac address map | ||
1209 | * located at address 0x400C | ||
1210 | */ | ||
1211 | typedef union _RXMAC_WOL_CRC34_t { | ||
1212 | u32 value; | ||
1213 | struct { | ||
1214 | #ifdef _BIT_FIELDS_HTOL | ||
1215 | u32 crc4:16; // bits 16-31 | ||
1216 | u32 crc3:16; // bits 0-15 | ||
1217 | #else | ||
1218 | u32 crc3:16; // bits 0-15 | ||
1219 | u32 crc4:16; // bits 16-31 | ||
1220 | #endif | ||
1221 | } bits; | ||
1222 | } RXMAC_WOL_CRC34_t, *PRXMAC_WOL_CRC34_t; | ||
1223 | |||
1224 | /* | ||
1225 | * structure for Wake On Lan Source Address Lo reg in rxmac address map | ||
1226 | * located at address 0x4010 | ||
1227 | */ | ||
1228 | typedef union _RXMAC_WOL_SA_LO_t { | ||
1229 | u32 value; | ||
1230 | struct { | ||
1231 | #ifdef _BIT_FIELDS_HTOL | ||
1232 | u32 sa3:8; // bits 24-31 | ||
1233 | u32 sa4:8; // bits 16-23 | ||
1234 | u32 sa5:8; // bits 8-15 | ||
1235 | u32 sa6:8; // bits 0-7 | ||
1236 | #else | ||
1237 | u32 sa6:8; // bits 0-7 | ||
1238 | u32 sa5:8; // bits 8-15 | ||
1239 | u32 sa4:8; // bits 16-23 | ||
1240 | u32 sa3:8; // bits 24-31 | ||
1241 | #endif | ||
1242 | } bits; | ||
1243 | } RXMAC_WOL_SA_LO_t, *PRXMAC_WOL_SA_LO_t; | ||
1244 | |||
1245 | /* | ||
1246 | * structure for Wake On Lan Source Address Hi reg in rxmac address map | ||
1247 | * located at address 0x4014 | ||
1248 | */ | ||
1249 | typedef union _RXMAC_WOL_SA_HI_t { | ||
1250 | u32 value; | ||
1251 | struct { | ||
1252 | #ifdef _BIT_FIELDS_HTOL | ||
1253 | u32 reserved:16; // bits 16-31 | ||
1254 | u32 sa1:8; // bits 8-15 | ||
1255 | u32 sa2:8; // bits 0-7 | ||
1256 | #else | ||
1257 | u32 sa2:8; // bits 0-7 | ||
1258 | u32 sa1:8; // bits 8-15 | ||
1259 | u32 reserved:16; // bits 16-31 | ||
1260 | #endif | ||
1261 | } bits; | ||
1262 | } RXMAC_WOL_SA_HI_t, *PRXMAC_WOL_SA_HI_t; | ||
1263 | |||
1264 | /* | ||
1265 | * structure for Wake On Lan mask reg in rxmac address map | ||
1266 | * located at address 0x4018 - 0x4064 | ||
1267 | * Defined earlier (u32) | ||
1268 | */ | ||
1269 | |||
1270 | /* | ||
1271 | * structure for Unicast Paket Filter Address 1 reg in rxmac address map | ||
1272 | * located at address 0x4068 | ||
1273 | */ | ||
1274 | typedef union _RXMAC_UNI_PF_ADDR1_t { | ||
1275 | u32 value; | ||
1276 | struct { | ||
1277 | #ifdef _BIT_FIELDS_HTOL | ||
1278 | u32 addr1_3:8; // bits 24-31 | ||
1279 | u32 addr1_4:8; // bits 16-23 | ||
1280 | u32 addr1_5:8; // bits 8-15 | ||
1281 | u32 addr1_6:8; // bits 0-7 | ||
1282 | #else | ||
1283 | u32 addr1_6:8; // bits 0-7 | ||
1284 | u32 addr1_5:8; // bits 8-15 | ||
1285 | u32 addr1_4:8; // bits 16-23 | ||
1286 | u32 addr1_3:8; // bits 24-31 | ||
1287 | #endif | ||
1288 | } bits; | ||
1289 | } RXMAC_UNI_PF_ADDR1_t, *PRXMAC_UNI_PF_ADDR1_t; | ||
1290 | |||
1291 | /* | ||
1292 | * structure for Unicast Paket Filter Address 2 reg in rxmac address map | ||
1293 | * located at address 0x406C | ||
1294 | */ | ||
1295 | typedef union _RXMAC_UNI_PF_ADDR2_t { | ||
1296 | u32 value; | ||
1297 | struct { | ||
1298 | #ifdef _BIT_FIELDS_HTOL | ||
1299 | u32 addr2_3:8; // bits 24-31 | ||
1300 | u32 addr2_4:8; // bits 16-23 | ||
1301 | u32 addr2_5:8; // bits 8-15 | ||
1302 | u32 addr2_6:8; // bits 0-7 | ||
1303 | #else | ||
1304 | u32 addr2_6:8; // bits 0-7 | ||
1305 | u32 addr2_5:8; // bits 8-15 | ||
1306 | u32 addr2_4:8; // bits 16-23 | ||
1307 | u32 addr2_3:8; // bits 24-31 | ||
1308 | #endif | ||
1309 | } bits; | ||
1310 | } RXMAC_UNI_PF_ADDR2_t, *PRXMAC_UNI_PF_ADDR2_t; | ||
1311 | |||
1312 | /* | ||
1313 | * structure for Unicast Paket Filter Address 1 & 2 reg in rxmac address map | ||
1314 | * located at address 0x4070 | ||
1315 | */ | ||
1316 | typedef union _RXMAC_UNI_PF_ADDR3_t { | ||
1317 | u32 value; | ||
1318 | struct { | ||
1319 | #ifdef _BIT_FIELDS_HTOL | ||
1320 | u32 addr2_1:8; // bits 24-31 | ||
1321 | u32 addr2_2:8; // bits 16-23 | ||
1322 | u32 addr1_1:8; // bits 8-15 | ||
1323 | u32 addr1_2:8; // bits 0-7 | ||
1324 | #else | ||
1325 | u32 addr1_2:8; // bits 0-7 | ||
1326 | u32 addr1_1:8; // bits 8-15 | ||
1327 | u32 addr2_2:8; // bits 16-23 | ||
1328 | u32 addr2_1:8; // bits 24-31 | ||
1329 | #endif | ||
1330 | } bits; | ||
1331 | } RXMAC_UNI_PF_ADDR3_t, *PRXMAC_UNI_PF_ADDR3_t; | ||
1332 | |||
1333 | /* | ||
1334 | * structure for Multicast Hash reg in rxmac address map | ||
1335 | * located at address 0x4074 - 0x4080 | ||
1336 | * Defined earlier (u32) | ||
1337 | */ | ||
1338 | |||
1339 | /* | ||
1340 | * structure for Packet Filter Control reg in rxmac address map | ||
1341 | * located at address 0x4084 | ||
1342 | */ | ||
1343 | typedef union _RXMAC_PF_CTRL_t { | ||
1344 | u32 value; | ||
1345 | struct { | ||
1346 | #ifdef _BIT_FIELDS_HTOL | ||
1347 | u32 unused2:9; // bits 23-31 | ||
1348 | u32 min_pkt_size:7; // bits 16-22 | ||
1349 | u32 unused1:12; // bits 4-15 | ||
1350 | u32 filter_frag_en:1; // bit 3 | ||
1351 | u32 filter_uni_en:1; // bit 2 | ||
1352 | u32 filter_multi_en:1; // bit 1 | ||
1353 | u32 filter_broad_en:1; // bit 0 | ||
1354 | #else | ||
1355 | u32 filter_broad_en:1; // bit 0 | ||
1356 | u32 filter_multi_en:1; // bit 1 | ||
1357 | u32 filter_uni_en:1; // bit 2 | ||
1358 | u32 filter_frag_en:1; // bit 3 | ||
1359 | u32 unused1:12; // bits 4-15 | ||
1360 | u32 min_pkt_size:7; // bits 16-22 | ||
1361 | u32 unused2:9; // bits 23-31 | ||
1362 | #endif | ||
1363 | } bits; | ||
1364 | } RXMAC_PF_CTRL_t, *PRXMAC_PF_CTRL_t; | ||
1365 | |||
1366 | /* | ||
1367 | * structure for Memory Controller Interface Control Max Segment reg in rxmac | ||
1368 | * address map. Located at address 0x4088 | ||
1369 | */ | ||
1370 | typedef union _RXMAC_MCIF_CTRL_MAX_SEG_t { | ||
1371 | u32 value; | ||
1372 | struct { | ||
1373 | #ifdef _BIT_FIELDS_HTOL | ||
1374 | u32 reserved:22; // bits 10-31 | ||
1375 | u32 max_size:8; // bits 2-9 | ||
1376 | u32 fc_en:1; // bit 1 | ||
1377 | u32 seg_en:1; // bit 0 | ||
1378 | #else | ||
1379 | u32 seg_en:1; // bit 0 | ||
1380 | u32 fc_en:1; // bit 1 | ||
1381 | u32 max_size:8; // bits 2-9 | ||
1382 | u32 reserved:22; // bits 10-31 | ||
1383 | #endif | ||
1384 | } bits; | ||
1385 | } RXMAC_MCIF_CTRL_MAX_SEG_t, *PRXMAC_MCIF_CTRL_MAX_SEG_t; | ||
1386 | |||
1387 | /* | ||
1388 | * structure for Memory Controller Interface Water Mark reg in rxmac address | ||
1389 | * map. Located at address 0x408C | ||
1390 | */ | ||
1391 | typedef union _RXMAC_MCIF_WATER_MARK_t { | ||
1392 | u32 value; | ||
1393 | struct { | ||
1394 | #ifdef _BIT_FIELDS_HTOL | ||
1395 | u32 reserved2:6; // bits 26-31 | ||
1396 | u32 mark_hi:10; // bits 16-25 | ||
1397 | u32 reserved1:6; // bits 10-15 | ||
1398 | u32 mark_lo:10; // bits 0-9 | ||
1399 | #else | ||
1400 | u32 mark_lo:10; // bits 0-9 | ||
1401 | u32 reserved1:6; // bits 10-15 | ||
1402 | u32 mark_hi:10; // bits 16-25 | ||
1403 | u32 reserved2:6; // bits 26-31 | ||
1404 | #endif | ||
1405 | } bits; | ||
1406 | } RXMAC_MCIF_WATER_MARK_t, *PRXMAC_MCIF_WATER_MARK_t; | ||
1407 | |||
1408 | /* | ||
1409 | * structure for Rx Queue Dialog reg in rxmac address map. | ||
1410 | * located at address 0x4090 | ||
1411 | */ | ||
1412 | typedef union _RXMAC_RXQ_DIAG_t { | ||
1413 | u32 value; | ||
1414 | struct { | ||
1415 | #ifdef _BIT_FIELDS_HTOL | ||
1416 | u32 reserved2:6; // bits 26-31 | ||
1417 | u32 rd_ptr:10; // bits 16-25 | ||
1418 | u32 reserved1:6; // bits 10-15 | ||
1419 | u32 wr_ptr:10; // bits 0-9 | ||
1420 | #else | ||
1421 | u32 wr_ptr:10; // bits 0-9 | ||
1422 | u32 reserved1:6; // bits 10-15 | ||
1423 | u32 rd_ptr:10; // bits 16-25 | ||
1424 | u32 reserved2:6; // bits 26-31 | ||
1425 | #endif | ||
1426 | } bits; | ||
1427 | } RXMAC_RXQ_DIAG_t, *PRXMAC_RXQ_DIAG_t; | ||
1428 | |||
1429 | /* | ||
1430 | * structure for space availiable reg in rxmac address map. | ||
1431 | * located at address 0x4094 | ||
1432 | */ | ||
1433 | typedef union _RXMAC_SPACE_AVAIL_t { | ||
1434 | u32 value; | ||
1435 | struct { | ||
1436 | #ifdef _BIT_FIELDS_HTOL | ||
1437 | u32 reserved2:15; // bits 17-31 | ||
1438 | u32 space_avail_en:1; // bit 16 | ||
1439 | u32 reserved1:6; // bits 10-15 | ||
1440 | u32 space_avail:10; // bits 0-9 | ||
1441 | #else | ||
1442 | u32 space_avail:10; // bits 0-9 | ||
1443 | u32 reserved1:6; // bits 10-15 | ||
1444 | u32 space_avail_en:1; // bit 16 | ||
1445 | u32 reserved2:15; // bits 17-31 | ||
1446 | #endif | ||
1447 | } bits; | ||
1448 | } RXMAC_SPACE_AVAIL_t, *PRXMAC_SPACE_AVAIL_t; | ||
1449 | |||
1450 | /* | ||
1451 | * structure for management interface reg in rxmac address map. | ||
1452 | * located at address 0x4098 | ||
1453 | */ | ||
1454 | typedef union _RXMAC_MIF_CTL_t { | ||
1455 | u32 value; | ||
1456 | struct { | ||
1457 | #ifdef _BIT_FIELDS_HTOL | ||
1458 | u32 reserve:14; // bits 18-31 | ||
1459 | u32 drop_pkt_en:1; // bit 17 | ||
1460 | u32 drop_pkt_mask:17; // bits 0-16 | ||
1461 | #else | ||
1462 | u32 drop_pkt_mask:17; // bits 0-16 | ||
1463 | u32 drop_pkt_en:1; // bit 17 | ||
1464 | u32 reserve:14; // bits 18-31 | ||
1465 | #endif | ||
1466 | } bits; | ||
1467 | } RXMAC_MIF_CTL_t, *PRXMAC_MIF_CTL_t; | ||
1468 | |||
1469 | /* | ||
1470 | * structure for Error reg in rxmac address map. | ||
1471 | * located at address 0x409C | ||
1472 | */ | ||
1473 | typedef union _RXMAC_ERROR_REG_t { | ||
1474 | u32 value; | ||
1475 | struct { | ||
1476 | #ifdef _BIT_FIELDS_HTOL | ||
1477 | u32 reserve:28; // bits 4-31 | ||
1478 | u32 mif:1; // bit 3 | ||
1479 | u32 async:1; // bit 2 | ||
1480 | u32 pkt_filter:1; // bit 1 | ||
1481 | u32 mcif:1; // bit 0 | ||
1482 | #else | ||
1483 | u32 mcif:1; // bit 0 | ||
1484 | u32 pkt_filter:1; // bit 1 | ||
1485 | u32 async:1; // bit 2 | ||
1486 | u32 mif:1; // bit 3 | ||
1487 | u32 reserve:28; // bits 4-31 | ||
1488 | #endif | ||
1489 | } bits; | ||
1490 | } RXMAC_ERROR_REG_t, *PRXMAC_ERROR_REG_t; | ||
1491 | |||
1492 | /* | ||
1493 | * Rx MAC Module of JAGCore Address Mapping | ||
1494 | */ | ||
1495 | typedef struct _RXMAC_t { // Location: | ||
1496 | RXMAC_CTRL_t ctrl; // 0x4000 | ||
1497 | RXMAC_WOL_CTL_CRC0_t crc0; // 0x4004 | ||
1498 | RXMAC_WOL_CRC12_t crc12; // 0x4008 | ||
1499 | RXMAC_WOL_CRC34_t crc34; // 0x400C | ||
1500 | RXMAC_WOL_SA_LO_t sa_lo; // 0x4010 | ||
1501 | RXMAC_WOL_SA_HI_t sa_hi; // 0x4014 | ||
1502 | u32 mask0_word0; // 0x4018 | ||
1503 | u32 mask0_word1; // 0x401C | ||
1504 | u32 mask0_word2; // 0x4020 | ||
1505 | u32 mask0_word3; // 0x4024 | ||
1506 | u32 mask1_word0; // 0x4028 | ||
1507 | u32 mask1_word1; // 0x402C | ||
1508 | u32 mask1_word2; // 0x4030 | ||
1509 | u32 mask1_word3; // 0x4034 | ||
1510 | u32 mask2_word0; // 0x4038 | ||
1511 | u32 mask2_word1; // 0x403C | ||
1512 | u32 mask2_word2; // 0x4040 | ||
1513 | u32 mask2_word3; // 0x4044 | ||
1514 | u32 mask3_word0; // 0x4048 | ||
1515 | u32 mask3_word1; // 0x404C | ||
1516 | u32 mask3_word2; // 0x4050 | ||
1517 | u32 mask3_word3; // 0x4054 | ||
1518 | u32 mask4_word0; // 0x4058 | ||
1519 | u32 mask4_word1; // 0x405C | ||
1520 | u32 mask4_word2; // 0x4060 | ||
1521 | u32 mask4_word3; // 0x4064 | ||
1522 | RXMAC_UNI_PF_ADDR1_t uni_pf_addr1; // 0x4068 | ||
1523 | RXMAC_UNI_PF_ADDR2_t uni_pf_addr2; // 0x406C | ||
1524 | RXMAC_UNI_PF_ADDR3_t uni_pf_addr3; // 0x4070 | ||
1525 | u32 multi_hash1; // 0x4074 | ||
1526 | u32 multi_hash2; // 0x4078 | ||
1527 | u32 multi_hash3; // 0x407C | ||
1528 | u32 multi_hash4; // 0x4080 | ||
1529 | RXMAC_PF_CTRL_t pf_ctrl; // 0x4084 | ||
1530 | RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; // 0x4088 | ||
1531 | RXMAC_MCIF_WATER_MARK_t mcif_water_mark; // 0x408C | ||
1532 | RXMAC_RXQ_DIAG_t rxq_diag; // 0x4090 | ||
1533 | RXMAC_SPACE_AVAIL_t space_avail; // 0x4094 | ||
1534 | |||
1535 | RXMAC_MIF_CTL_t mif_ctrl; // 0x4098 | ||
1536 | RXMAC_ERROR_REG_t err_reg; // 0x409C | ||
1537 | } RXMAC_t, *PRXMAC_t; | ||
1538 | |||
1539 | /* END OF TXMAC REGISTER ADDRESS MAP */ | ||
1540 | |||
1541 | |||
1542 | /* START OF MAC REGISTER ADDRESS MAP */ | ||
1543 | |||
1544 | /* | ||
1545 | * structure for configuration #1 reg in mac address map. | ||
1546 | * located at address 0x5000 | ||
1547 | */ | ||
1548 | typedef union _MAC_CFG1_t { | ||
1549 | u32 value; | ||
1550 | struct { | ||
1551 | #ifdef _BIT_FIELDS_HTOL | ||
1552 | u32 soft_reset:1; // bit 31 | ||
1553 | u32 sim_reset:1; // bit 30 | ||
1554 | u32 reserved3:10; // bits 20-29 | ||
1555 | u32 reset_rx_mc:1; // bit 19 | ||
1556 | u32 reset_tx_mc:1; // bit 18 | ||
1557 | u32 reset_rx_fun:1; // bit 17 | ||
1558 | u32 reset_tx_fun:1; // bit 16 | ||
1559 | u32 reserved2:7; // bits 9-15 | ||
1560 | u32 loop_back:1; // bit 8 | ||
1561 | u32 reserved1:2; // bits 6-7 | ||
1562 | u32 rx_flow:1; // bit 5 | ||
1563 | u32 tx_flow:1; // bit 4 | ||
1564 | u32 syncd_rx_en:1; // bit 3 | ||
1565 | u32 rx_enable:1; // bit 2 | ||
1566 | u32 syncd_tx_en:1; // bit 1 | ||
1567 | u32 tx_enable:1; // bit 0 | ||
1568 | #else | ||
1569 | u32 tx_enable:1; // bit 0 | ||
1570 | u32 syncd_tx_en:1; // bit 1 | ||
1571 | u32 rx_enable:1; // bit 2 | ||
1572 | u32 syncd_rx_en:1; // bit 3 | ||
1573 | u32 tx_flow:1; // bit 4 | ||
1574 | u32 rx_flow:1; // bit 5 | ||
1575 | u32 reserved1:2; // bits 6-7 | ||
1576 | u32 loop_back:1; // bit 8 | ||
1577 | u32 reserved2:7; // bits 9-15 | ||
1578 | u32 reset_tx_fun:1; // bit 16 | ||
1579 | u32 reset_rx_fun:1; // bit 17 | ||
1580 | u32 reset_tx_mc:1; // bit 18 | ||
1581 | u32 reset_rx_mc:1; // bit 19 | ||
1582 | u32 reserved3:10; // bits 20-29 | ||
1583 | u32 sim_reset:1; // bit 30 | ||
1584 | u32 soft_reset:1; // bit 31 | ||
1585 | #endif | ||
1586 | } bits; | ||
1587 | } MAC_CFG1_t, *PMAC_CFG1_t; | ||
1588 | |||
1589 | /* | ||
1590 | * structure for configuration #2 reg in mac address map. | ||
1591 | * located at address 0x5004 | ||
1592 | */ | ||
1593 | typedef union _MAC_CFG2_t { | ||
1594 | u32 value; | ||
1595 | struct { | ||
1596 | #ifdef _BIT_FIELDS_HTOL | ||
1597 | u32 reserved3:16; // bits 16-31 | ||
1598 | u32 preamble_len:4; // bits 12-15 | ||
1599 | u32 reserved2:2; // bits 10-11 | ||
1600 | u32 if_mode:2; // bits 8-9 | ||
1601 | u32 reserved1:2; // bits 6-7 | ||
1602 | u32 huge_frame:1; // bit 5 | ||
1603 | u32 len_check:1; // bit 4 | ||
1604 | u32 undefined:1; // bit 3 | ||
1605 | u32 pad_crc:1; // bit 2 | ||
1606 | u32 crc_enable:1; // bit 1 | ||
1607 | u32 full_duplex:1; // bit 0 | ||
1608 | #else | ||
1609 | u32 full_duplex:1; // bit 0 | ||
1610 | u32 crc_enable:1; // bit 1 | ||
1611 | u32 pad_crc:1; // bit 2 | ||
1612 | u32 undefined:1; // bit 3 | ||
1613 | u32 len_check:1; // bit 4 | ||
1614 | u32 huge_frame:1; // bit 5 | ||
1615 | u32 reserved1:2; // bits 6-7 | ||
1616 | u32 if_mode:2; // bits 8-9 | ||
1617 | u32 reserved2:2; // bits 10-11 | ||
1618 | u32 preamble_len:4; // bits 12-15 | ||
1619 | u32 reserved3:16; // bits 16-31 | ||
1620 | #endif | ||
1621 | } bits; | ||
1622 | } MAC_CFG2_t, *PMAC_CFG2_t; | ||
1623 | |||
1624 | /* | ||
1625 | * structure for Interpacket gap reg in mac address map. | ||
1626 | * located at address 0x5008 | ||
1627 | */ | ||
1628 | typedef union _MAC_IPG_t { | ||
1629 | u32 value; | ||
1630 | struct { | ||
1631 | #ifdef _BIT_FIELDS_HTOL | ||
1632 | u32 reserved:1; // bit 31 | ||
1633 | u32 non_B2B_ipg_1:7; // bits 24-30 | ||
1634 | u32 undefined2:1; // bit 23 | ||
1635 | u32 non_B2B_ipg_2:7; // bits 16-22 | ||
1636 | u32 min_ifg_enforce:8; // bits 8-15 | ||
1637 | u32 undefined1:1; // bit 7 | ||
1638 | u32 B2B_ipg:7; // bits 0-6 | ||
1639 | #else | ||
1640 | u32 B2B_ipg:7; // bits 0-6 | ||
1641 | u32 undefined1:1; // bit 7 | ||
1642 | u32 min_ifg_enforce:8; // bits 8-15 | ||
1643 | u32 non_B2B_ipg_2:7; // bits 16-22 | ||
1644 | u32 undefined2:1; // bit 23 | ||
1645 | u32 non_B2B_ipg_1:7; // bits 24-30 | ||
1646 | u32 reserved:1; // bit 31 | ||
1647 | #endif | ||
1648 | } bits; | ||
1649 | } MAC_IPG_t, *PMAC_IPG_t; | ||
1650 | |||
1651 | /* | ||
1652 | * structure for half duplex reg in mac address map. | ||
1653 | * located at address 0x500C | ||
1654 | */ | ||
1655 | typedef union _MAC_HFDP_t { | ||
1656 | u32 value; | ||
1657 | struct { | ||
1658 | #ifdef _BIT_FIELDS_HTOL | ||
1659 | u32 reserved2:8; // bits 24-31 | ||
1660 | u32 alt_beb_trunc:4; // bits 23-20 | ||
1661 | u32 alt_beb_enable:1; // bit 19 | ||
1662 | u32 bp_no_backoff:1; // bit 18 | ||
1663 | u32 no_backoff:1; // bit 17 | ||
1664 | u32 excess_defer:1; // bit 16 | ||
1665 | u32 rexmit_max:4; // bits 12-15 | ||
1666 | u32 reserved1:2; // bits 10-11 | ||
1667 | u32 coll_window:10; // bits 0-9 | ||
1668 | #else | ||
1669 | u32 coll_window:10; // bits 0-9 | ||
1670 | u32 reserved1:2; // bits 10-11 | ||
1671 | u32 rexmit_max:4; // bits 12-15 | ||
1672 | u32 excess_defer:1; // bit 16 | ||
1673 | u32 no_backoff:1; // bit 17 | ||
1674 | u32 bp_no_backoff:1; // bit 18 | ||
1675 | u32 alt_beb_enable:1; // bit 19 | ||
1676 | u32 alt_beb_trunc:4; // bits 23-20 | ||
1677 | u32 reserved2:8; // bits 24-31 | ||
1678 | #endif | ||
1679 | } bits; | ||
1680 | } MAC_HFDP_t, *PMAC_HFDP_t; | ||
1681 | |||
1682 | /* | ||
1683 | * structure for Maximum Frame Length reg in mac address map. | ||
1684 | * located at address 0x5010 | ||
1685 | */ | ||
1686 | typedef union _MAC_MAX_FM_LEN_t { | ||
1687 | u32 value; | ||
1688 | struct { | ||
1689 | #ifdef _BIT_FIELDS_HTOL | ||
1690 | u32 reserved:16; // bits 16-31 | ||
1691 | u32 max_len:16; // bits 0-15 | ||
1692 | #else | ||
1693 | u32 max_len:16; // bits 0-15 | ||
1694 | u32 reserved:16; // bits 16-31 | ||
1695 | #endif | ||
1696 | } bits; | ||
1697 | } MAC_MAX_FM_LEN_t, *PMAC_MAX_FM_LEN_t; | ||
1698 | |||
1699 | /* | ||
1700 | * structure for Reserve 1 reg in mac address map. | ||
1701 | * located at address 0x5014 - 0x5018 | ||
1702 | * Defined earlier (u32) | ||
1703 | */ | ||
1704 | |||
1705 | /* | ||
1706 | * structure for Test reg in mac address map. | ||
1707 | * located at address 0x501C | ||
1708 | */ | ||
1709 | typedef union _MAC_TEST_t { | ||
1710 | u32 value; | ||
1711 | struct { | ||
1712 | #ifdef _BIT_FIELDS_HTOL | ||
1713 | u32 unused:29; // bits 3-31 | ||
1714 | u32 mac_test:3; // bits 0-2 | ||
1715 | #else | ||
1716 | u32 mac_test:3; // bits 0-2 | ||
1717 | u32 unused:29; // bits 3-31 | ||
1718 | #endif | ||
1719 | } bits; | ||
1720 | } MAC_TEST_t, *PMAC_TEST_t; | ||
1721 | |||
1722 | /* | ||
1723 | * structure for MII Management Configuration reg in mac address map. | ||
1724 | * located at address 0x5020 | ||
1725 | */ | ||
1726 | typedef union _MII_MGMT_CFG_t { | ||
1727 | u32 value; | ||
1728 | struct { | ||
1729 | #ifdef _BIT_FIELDS_HTOL | ||
1730 | u32 reset_mii_mgmt:1; // bit 31 | ||
1731 | u32 reserved:25; // bits 6-30 | ||
1732 | u32 scan_auto_incremt:1; // bit 5 | ||
1733 | u32 preamble_suppress:1; // bit 4 | ||
1734 | u32 undefined:1; // bit 3 | ||
1735 | u32 mgmt_clk_reset:3; // bits 0-2 | ||
1736 | #else | ||
1737 | u32 mgmt_clk_reset:3; // bits 0-2 | ||
1738 | u32 undefined:1; // bit 3 | ||
1739 | u32 preamble_suppress:1; // bit 4 | ||
1740 | u32 scan_auto_incremt:1; // bit 5 | ||
1741 | u32 reserved:25; // bits 6-30 | ||
1742 | u32 reset_mii_mgmt:1; // bit 31 | ||
1743 | #endif | ||
1744 | } bits; | ||
1745 | } MII_MGMT_CFG_t, *PMII_MGMT_CFG_t; | ||
1746 | |||
1747 | /* | ||
1748 | * structure for MII Management Command reg in mac address map. | ||
1749 | * located at address 0x5024 | ||
1750 | */ | ||
1751 | typedef union _MII_MGMT_CMD_t { | ||
1752 | u32 value; | ||
1753 | struct { | ||
1754 | #ifdef _BIT_FIELDS_HTOL | ||
1755 | u32 reserved:30; // bits 2-31 | ||
1756 | u32 scan_cycle:1; // bit 1 | ||
1757 | u32 read_cycle:1; // bit 0 | ||
1758 | #else | ||
1759 | u32 read_cycle:1; // bit 0 | ||
1760 | u32 scan_cycle:1; // bit 1 | ||
1761 | u32 reserved:30; // bits 2-31 | ||
1762 | #endif | ||
1763 | } bits; | ||
1764 | } MII_MGMT_CMD_t, *PMII_MGMT_CMD_t; | ||
1765 | |||
1766 | /* | ||
1767 | * structure for MII Management Address reg in mac address map. | ||
1768 | * located at address 0x5028 | ||
1769 | */ | ||
1770 | typedef union _MII_MGMT_ADDR_t { | ||
1771 | u32 value; | ||
1772 | struct { | ||
1773 | #ifdef _BIT_FIELDS_HTOL | ||
1774 | u32 reserved2:19; // bit 13-31 | ||
1775 | u32 phy_addr:5; // bits 8-12 | ||
1776 | u32 reserved1:3; // bits 5-7 | ||
1777 | u32 reg_addr:5; // bits 0-4 | ||
1778 | #else | ||
1779 | u32 reg_addr:5; // bits 0-4 | ||
1780 | u32 reserved1:3; // bits 5-7 | ||
1781 | u32 phy_addr:5; // bits 8-12 | ||
1782 | u32 reserved2:19; // bit 13-31 | ||
1783 | #endif | ||
1784 | } bits; | ||
1785 | } MII_MGMT_ADDR_t, *PMII_MGMT_ADDR_t; | ||
1786 | |||
1787 | /* | ||
1788 | * structure for MII Management Control reg in mac address map. | ||
1789 | * located at address 0x502C | ||
1790 | */ | ||
1791 | typedef union _MII_MGMT_CTRL_t { | ||
1792 | u32 value; | ||
1793 | struct { | ||
1794 | #ifdef _BIT_FIELDS_HTOL | ||
1795 | u32 reserved:16; // bits 16-31 | ||
1796 | u32 phy_ctrl:16; // bits 0-15 | ||
1797 | #else | ||
1798 | u32 phy_ctrl:16; // bits 0-15 | ||
1799 | u32 reserved:16; // bits 16-31 | ||
1800 | #endif | ||
1801 | } bits; | ||
1802 | } MII_MGMT_CTRL_t, *PMII_MGMT_CTRL_t; | ||
1803 | |||
1804 | /* | ||
1805 | * structure for MII Management Status reg in mac address map. | ||
1806 | * located at address 0x5030 | ||
1807 | */ | ||
1808 | typedef union _MII_MGMT_STAT_t { | ||
1809 | u32 value; | ||
1810 | struct { | ||
1811 | #ifdef _BIT_FIELDS_HTOL | ||
1812 | u32 reserved:16; // bits 16-31 | ||
1813 | u32 phy_stat:16; // bits 0-15 | ||
1814 | #else | ||
1815 | u32 phy_stat:16; // bits 0-15 | ||
1816 | u32 reserved:16; // bits 16-31 | ||
1817 | #endif | ||
1818 | } bits; | ||
1819 | } MII_MGMT_STAT_t, *PMII_MGMT_STAT_t; | ||
1820 | |||
1821 | /* | ||
1822 | * structure for MII Management Indicators reg in mac address map. | ||
1823 | * located at address 0x5034 | ||
1824 | */ | ||
1825 | typedef union _MII_MGMT_INDICATOR_t { | ||
1826 | u32 value; | ||
1827 | struct { | ||
1828 | #ifdef _BIT_FIELDS_HTOL | ||
1829 | u32 reserved:29; // bits 3-31 | ||
1830 | u32 not_valid:1; // bit 2 | ||
1831 | u32 scanning:1; // bit 1 | ||
1832 | u32 busy:1; // bit 0 | ||
1833 | #else | ||
1834 | u32 busy:1; // bit 0 | ||
1835 | u32 scanning:1; // bit 1 | ||
1836 | u32 not_valid:1; // bit 2 | ||
1837 | u32 reserved:29; // bits 3-31 | ||
1838 | #endif | ||
1839 | } bits; | ||
1840 | } MII_MGMT_INDICATOR_t, *PMII_MGMT_INDICATOR_t; | ||
1841 | |||
1842 | /* | ||
1843 | * structure for Interface Control reg in mac address map. | ||
1844 | * located at address 0x5038 | ||
1845 | */ | ||
1846 | typedef union _MAC_IF_CTRL_t { | ||
1847 | u32 value; | ||
1848 | struct { | ||
1849 | #ifdef _BIT_FIELDS_HTOL | ||
1850 | u32 reset_if_module:1; // bit 31 | ||
1851 | u32 reserved4:3; // bit 28-30 | ||
1852 | u32 tbi_mode:1; // bit 27 | ||
1853 | u32 ghd_mode:1; // bit 26 | ||
1854 | u32 lhd_mode:1; // bit 25 | ||
1855 | u32 phy_mode:1; // bit 24 | ||
1856 | u32 reset_per_mii:1; // bit 23 | ||
1857 | u32 reserved3:6; // bits 17-22 | ||
1858 | u32 speed:1; // bit 16 | ||
1859 | u32 reset_pe100x:1; // bit 15 | ||
1860 | u32 reserved2:4; // bits 11-14 | ||
1861 | u32 force_quiet:1; // bit 10 | ||
1862 | u32 no_cipher:1; // bit 9 | ||
1863 | u32 disable_link_fail:1; // bit 8 | ||
1864 | u32 reset_gpsi:1; // bit 7 | ||
1865 | u32 reserved1:6; // bits 1-6 | ||
1866 | u32 enab_jab_protect:1; // bit 0 | ||
1867 | #else | ||
1868 | u32 enab_jab_protect:1; // bit 0 | ||
1869 | u32 reserved1:6; // bits 1-6 | ||
1870 | u32 reset_gpsi:1; // bit 7 | ||
1871 | u32 disable_link_fail:1; // bit 8 | ||
1872 | u32 no_cipher:1; // bit 9 | ||
1873 | u32 force_quiet:1; // bit 10 | ||
1874 | u32 reserved2:4; // bits 11-14 | ||
1875 | u32 reset_pe100x:1; // bit 15 | ||
1876 | u32 speed:1; // bit 16 | ||
1877 | u32 reserved3:6; // bits 17-22 | ||
1878 | u32 reset_per_mii:1; // bit 23 | ||
1879 | u32 phy_mode:1; // bit 24 | ||
1880 | u32 lhd_mode:1; // bit 25 | ||
1881 | u32 ghd_mode:1; // bit 26 | ||
1882 | u32 tbi_mode:1; // bit 27 | ||
1883 | u32 reserved4:3; // bit 28-30 | ||
1884 | u32 reset_if_module:1; // bit 31 | ||
1885 | #endif | ||
1886 | } bits; | ||
1887 | } MAC_IF_CTRL_t, *PMAC_IF_CTRL_t; | ||
1888 | |||
1889 | /* | ||
1890 | * structure for Interface Status reg in mac address map. | ||
1891 | * located at address 0x503C | ||
1892 | */ | ||
1893 | typedef union _MAC_IF_STAT_t { | ||
1894 | u32 value; | ||
1895 | struct { | ||
1896 | #ifdef _BIT_FIELDS_HTOL | ||
1897 | u32 reserved:22; // bits 10-31 | ||
1898 | u32 excess_defer:1; // bit 9 | ||
1899 | u32 clash:1; // bit 8 | ||
1900 | u32 phy_jabber:1; // bit 7 | ||
1901 | u32 phy_link_ok:1; // bit 6 | ||
1902 | u32 phy_full_duplex:1; // bit 5 | ||
1903 | u32 phy_speed:1; // bit 4 | ||
1904 | u32 pe100x_link_fail:1; // bit 3 | ||
1905 | u32 pe10t_loss_carrie:1; // bit 2 | ||
1906 | u32 pe10t_sqe_error:1; // bit 1 | ||
1907 | u32 pe10t_jabber:1; // bit 0 | ||
1908 | #else | ||
1909 | u32 pe10t_jabber:1; // bit 0 | ||
1910 | u32 pe10t_sqe_error:1; // bit 1 | ||
1911 | u32 pe10t_loss_carrie:1; // bit 2 | ||
1912 | u32 pe100x_link_fail:1; // bit 3 | ||
1913 | u32 phy_speed:1; // bit 4 | ||
1914 | u32 phy_full_duplex:1; // bit 5 | ||
1915 | u32 phy_link_ok:1; // bit 6 | ||
1916 | u32 phy_jabber:1; // bit 7 | ||
1917 | u32 clash:1; // bit 8 | ||
1918 | u32 excess_defer:1; // bit 9 | ||
1919 | u32 reserved:22; // bits 10-31 | ||
1920 | #endif | ||
1921 | } bits; | ||
1922 | } MAC_IF_STAT_t, *PMAC_IF_STAT_t; | ||
1923 | |||
1924 | /* | ||
1925 | * structure for Mac Station Address, Part 1 reg in mac address map. | ||
1926 | * located at address 0x5040 | ||
1927 | */ | ||
1928 | typedef union _MAC_STATION_ADDR1_t { | ||
1929 | u32 value; | ||
1930 | struct { | ||
1931 | #ifdef _BIT_FIELDS_HTOL | ||
1932 | u32 Octet6:8; // bits 24-31 | ||
1933 | u32 Octet5:8; // bits 16-23 | ||
1934 | u32 Octet4:8; // bits 8-15 | ||
1935 | u32 Octet3:8; // bits 0-7 | ||
1936 | #else | ||
1937 | u32 Octet3:8; // bits 0-7 | ||
1938 | u32 Octet4:8; // bits 8-15 | ||
1939 | u32 Octet5:8; // bits 16-23 | ||
1940 | u32 Octet6:8; // bits 24-31 | ||
1941 | #endif | ||
1942 | } bits; | ||
1943 | } MAC_STATION_ADDR1_t, *PMAC_STATION_ADDR1_t; | ||
1944 | |||
1945 | /* | ||
1946 | * structure for Mac Station Address, Part 2 reg in mac address map. | ||
1947 | * located at address 0x5044 | ||
1948 | */ | ||
1949 | typedef union _MAC_STATION_ADDR2_t { | ||
1950 | u32 value; | ||
1951 | struct { | ||
1952 | #ifdef _BIT_FIELDS_HTOL | ||
1953 | u32 Octet2:8; // bits 24-31 | ||
1954 | u32 Octet1:8; // bits 16-23 | ||
1955 | u32 reserved:16; // bits 0-15 | ||
1956 | #else | ||
1957 | u32 reserved:16; // bit 0-15 | ||
1958 | u32 Octet1:8; // bits 16-23 | ||
1959 | u32 Octet2:8; // bits 24-31 | ||
1960 | #endif | ||
1961 | } bits; | ||
1962 | } MAC_STATION_ADDR2_t, *PMAC_STATION_ADDR2_t; | ||
1963 | |||
1964 | /* | ||
1965 | * MAC Module of JAGCore Address Mapping | ||
1966 | */ | ||
1967 | typedef struct _MAC_t { // Location: | ||
1968 | MAC_CFG1_t cfg1; // 0x5000 | ||
1969 | MAC_CFG2_t cfg2; // 0x5004 | ||
1970 | MAC_IPG_t ipg; // 0x5008 | ||
1971 | MAC_HFDP_t hfdp; // 0x500C | ||
1972 | MAC_MAX_FM_LEN_t max_fm_len; // 0x5010 | ||
1973 | u32 rsv1; // 0x5014 | ||
1974 | u32 rsv2; // 0x5018 | ||
1975 | MAC_TEST_t mac_test; // 0x501C | ||
1976 | MII_MGMT_CFG_t mii_mgmt_cfg; // 0x5020 | ||
1977 | MII_MGMT_CMD_t mii_mgmt_cmd; // 0x5024 | ||
1978 | MII_MGMT_ADDR_t mii_mgmt_addr; // 0x5028 | ||
1979 | MII_MGMT_CTRL_t mii_mgmt_ctrl; // 0x502C | ||
1980 | MII_MGMT_STAT_t mii_mgmt_stat; // 0x5030 | ||
1981 | MII_MGMT_INDICATOR_t mii_mgmt_indicator; // 0x5034 | ||
1982 | MAC_IF_CTRL_t if_ctrl; // 0x5038 | ||
1983 | MAC_IF_STAT_t if_stat; // 0x503C | ||
1984 | MAC_STATION_ADDR1_t station_addr_1; // 0x5040 | ||
1985 | MAC_STATION_ADDR2_t station_addr_2; // 0x5044 | ||
1986 | } MAC_t, *PMAC_t; | ||
1987 | |||
1988 | /* END OF MAC REGISTER ADDRESS MAP */ | ||
1989 | |||
1990 | /* START OF MAC STAT REGISTER ADDRESS MAP */ | ||
1991 | |||
1992 | /* | ||
1993 | * structure for Carry Register One and it's Mask Register reg located in mac | ||
1994 | * stat address map address 0x6130 and 0x6138. | ||
1995 | */ | ||
1996 | typedef union _MAC_STAT_REG_1_t { | ||
1997 | u32 value; | ||
1998 | struct { | ||
1999 | #ifdef _BIT_FIELDS_HTOL | ||
2000 | u32 tr64:1; // bit 31 | ||
2001 | u32 tr127:1; // bit 30 | ||
2002 | u32 tr255:1; // bit 29 | ||
2003 | u32 tr511:1; // bit 28 | ||
2004 | u32 tr1k:1; // bit 27 | ||
2005 | u32 trmax:1; // bit 26 | ||
2006 | u32 trmgv:1; // bit 25 | ||
2007 | u32 unused:8; // bits 17-24 | ||
2008 | u32 rbyt:1; // bit 16 | ||
2009 | u32 rpkt:1; // bit 15 | ||
2010 | u32 rfcs:1; // bit 14 | ||
2011 | u32 rmca:1; // bit 13 | ||
2012 | u32 rbca:1; // bit 12 | ||
2013 | u32 rxcf:1; // bit 11 | ||
2014 | u32 rxpf:1; // bit 10 | ||
2015 | u32 rxuo:1; // bit 9 | ||
2016 | u32 raln:1; // bit 8 | ||
2017 | u32 rflr:1; // bit 7 | ||
2018 | u32 rcde:1; // bit 6 | ||
2019 | u32 rcse:1; // bit 5 | ||
2020 | u32 rund:1; // bit 4 | ||
2021 | u32 rovr:1; // bit 3 | ||
2022 | u32 rfrg:1; // bit 2 | ||
2023 | u32 rjbr:1; // bit 1 | ||
2024 | u32 rdrp:1; // bit 0 | ||
2025 | #else | ||
2026 | u32 rdrp:1; // bit 0 | ||
2027 | u32 rjbr:1; // bit 1 | ||
2028 | u32 rfrg:1; // bit 2 | ||
2029 | u32 rovr:1; // bit 3 | ||
2030 | u32 rund:1; // bit 4 | ||
2031 | u32 rcse:1; // bit 5 | ||
2032 | u32 rcde:1; // bit 6 | ||
2033 | u32 rflr:1; // bit 7 | ||
2034 | u32 raln:1; // bit 8 | ||
2035 | u32 rxuo:1; // bit 9 | ||
2036 | u32 rxpf:1; // bit 10 | ||
2037 | u32 rxcf:1; // bit 11 | ||
2038 | u32 rbca:1; // bit 12 | ||
2039 | u32 rmca:1; // bit 13 | ||
2040 | u32 rfcs:1; // bit 14 | ||
2041 | u32 rpkt:1; // bit 15 | ||
2042 | u32 rbyt:1; // bit 16 | ||
2043 | u32 unused:8; // bits 17-24 | ||
2044 | u32 trmgv:1; // bit 25 | ||
2045 | u32 trmax:1; // bit 26 | ||
2046 | u32 tr1k:1; // bit 27 | ||
2047 | u32 tr511:1; // bit 28 | ||
2048 | u32 tr255:1; // bit 29 | ||
2049 | u32 tr127:1; // bit 30 | ||
2050 | u32 tr64:1; // bit 31 | ||
2051 | #endif | ||
2052 | } bits; | ||
2053 | } MAC_STAT_REG_1_t, *PMAC_STAT_REG_1_t; | ||
2054 | |||
2055 | /* | ||
2056 | * structure for Carry Register Two Mask Register reg in mac stat address map. | ||
2057 | * located at address 0x613C | ||
2058 | */ | ||
2059 | typedef union _MAC_STAT_REG_2_t { | ||
2060 | u32 value; | ||
2061 | struct { | ||
2062 | #ifdef _BIT_FIELDS_HTOL | ||
2063 | u32 unused:12; // bit 20-31 | ||
2064 | u32 tjbr:1; // bit 19 | ||
2065 | u32 tfcs:1; // bit 18 | ||
2066 | u32 txcf:1; // bit 17 | ||
2067 | u32 tovr:1; // bit 16 | ||
2068 | u32 tund:1; // bit 15 | ||
2069 | u32 tfrg:1; // bit 14 | ||
2070 | u32 tbyt:1; // bit 13 | ||
2071 | u32 tpkt:1; // bit 12 | ||
2072 | u32 tmca:1; // bit 11 | ||
2073 | u32 tbca:1; // bit 10 | ||
2074 | u32 txpf:1; // bit 9 | ||
2075 | u32 tdfr:1; // bit 8 | ||
2076 | u32 tedf:1; // bit 7 | ||
2077 | u32 tscl:1; // bit 6 | ||
2078 | u32 tmcl:1; // bit 5 | ||
2079 | u32 tlcl:1; // bit 4 | ||
2080 | u32 txcl:1; // bit 3 | ||
2081 | u32 tncl:1; // bit 2 | ||
2082 | u32 tpfh:1; // bit 1 | ||
2083 | u32 tdrp:1; // bit 0 | ||
2084 | #else | ||
2085 | u32 tdrp:1; // bit 0 | ||
2086 | u32 tpfh:1; // bit 1 | ||
2087 | u32 tncl:1; // bit 2 | ||
2088 | u32 txcl:1; // bit 3 | ||
2089 | u32 tlcl:1; // bit 4 | ||
2090 | u32 tmcl:1; // bit 5 | ||
2091 | u32 tscl:1; // bit 6 | ||
2092 | u32 tedf:1; // bit 7 | ||
2093 | u32 tdfr:1; // bit 8 | ||
2094 | u32 txpf:1; // bit 9 | ||
2095 | u32 tbca:1; // bit 10 | ||
2096 | u32 tmca:1; // bit 11 | ||
2097 | u32 tpkt:1; // bit 12 | ||
2098 | u32 tbyt:1; // bit 13 | ||
2099 | u32 tfrg:1; // bit 14 | ||
2100 | u32 tund:1; // bit 15 | ||
2101 | u32 tovr:1; // bit 16 | ||
2102 | u32 txcf:1; // bit 17 | ||
2103 | u32 tfcs:1; // bit 18 | ||
2104 | u32 tjbr:1; // bit 19 | ||
2105 | u32 unused:12; // bit 20-31 | ||
2106 | #endif | ||
2107 | } bits; | ||
2108 | } MAC_STAT_REG_2_t, *PMAC_STAT_REG_2_t; | ||
2109 | |||
2110 | /* | ||
2111 | * MAC STATS Module of JAGCore Address Mapping | ||
2112 | */ | ||
2113 | typedef struct _MAC_STAT_t { // Location: | ||
2114 | u32 pad[32]; // 0x6000 - 607C | ||
2115 | |||
2116 | // Tx/Rx 0-64 Byte Frame Counter | ||
2117 | u32 TR64; // 0x6080 | ||
2118 | |||
2119 | // Tx/Rx 65-127 Byte Frame Counter | ||
2120 | u32 TR127; // 0x6084 | ||
2121 | |||
2122 | // Tx/Rx 128-255 Byte Frame Counter | ||
2123 | u32 TR255; // 0x6088 | ||
2124 | |||
2125 | // Tx/Rx 256-511 Byte Frame Counter | ||
2126 | u32 TR511; // 0x608C | ||
2127 | |||
2128 | // Tx/Rx 512-1023 Byte Frame Counter | ||
2129 | u32 TR1K; // 0x6090 | ||
2130 | |||
2131 | // Tx/Rx 1024-1518 Byte Frame Counter | ||
2132 | u32 TRMax; // 0x6094 | ||
2133 | |||
2134 | // Tx/Rx 1519-1522 Byte Good VLAN Frame Count | ||
2135 | u32 TRMgv; // 0x6098 | ||
2136 | |||
2137 | // Rx Byte Counter | ||
2138 | u32 RByt; // 0x609C | ||
2139 | |||
2140 | // Rx Packet Counter | ||
2141 | u32 RPkt; // 0x60A0 | ||
2142 | |||
2143 | // Rx FCS Error Counter | ||
2144 | u32 RFcs; // 0x60A4 | ||
2145 | |||
2146 | // Rx Multicast Packet Counter | ||
2147 | u32 RMca; // 0x60A8 | ||
2148 | |||
2149 | // Rx Broadcast Packet Counter | ||
2150 | u32 RBca; // 0x60AC | ||
2151 | |||
2152 | // Rx Control Frame Packet Counter | ||
2153 | u32 RxCf; // 0x60B0 | ||
2154 | |||
2155 | // Rx Pause Frame Packet Counter | ||
2156 | u32 RxPf; // 0x60B4 | ||
2157 | |||
2158 | // Rx Unknown OP Code Counter | ||
2159 | u32 RxUo; // 0x60B8 | ||
2160 | |||
2161 | // Rx Alignment Error Counter | ||
2162 | u32 RAln; // 0x60BC | ||
2163 | |||
2164 | // Rx Frame Length Error Counter | ||
2165 | u32 RFlr; // 0x60C0 | ||
2166 | |||
2167 | // Rx Code Error Counter | ||
2168 | u32 RCde; // 0x60C4 | ||
2169 | |||
2170 | // Rx Carrier Sense Error Counter | ||
2171 | u32 RCse; // 0x60C8 | ||
2172 | |||
2173 | // Rx Undersize Packet Counter | ||
2174 | u32 RUnd; // 0x60CC | ||
2175 | |||
2176 | // Rx Oversize Packet Counter | ||
2177 | u32 ROvr; // 0x60D0 | ||
2178 | |||
2179 | // Rx Fragment Counter | ||
2180 | u32 RFrg; // 0x60D4 | ||
2181 | |||
2182 | // Rx Jabber Counter | ||
2183 | u32 RJbr; // 0x60D8 | ||
2184 | |||
2185 | // Rx Drop | ||
2186 | u32 RDrp; // 0x60DC | ||
2187 | |||
2188 | // Tx Byte Counter | ||
2189 | u32 TByt; // 0x60E0 | ||
2190 | |||
2191 | // Tx Packet Counter | ||
2192 | u32 TPkt; // 0x60E4 | ||
2193 | |||
2194 | // Tx Multicast Packet Counter | ||
2195 | u32 TMca; // 0x60E8 | ||
2196 | |||
2197 | // Tx Broadcast Packet Counter | ||
2198 | u32 TBca; // 0x60EC | ||
2199 | |||
2200 | // Tx Pause Control Frame Counter | ||
2201 | u32 TxPf; // 0x60F0 | ||
2202 | |||
2203 | // Tx Deferral Packet Counter | ||
2204 | u32 TDfr; // 0x60F4 | ||
2205 | |||
2206 | // Tx Excessive Deferral Packet Counter | ||
2207 | u32 TEdf; // 0x60F8 | ||
2208 | |||
2209 | // Tx Single Collision Packet Counter | ||
2210 | u32 TScl; // 0x60FC | ||
2211 | |||
2212 | // Tx Multiple Collision Packet Counter | ||
2213 | u32 TMcl; // 0x6100 | ||
2214 | |||
2215 | // Tx Late Collision Packet Counter | ||
2216 | u32 TLcl; // 0x6104 | ||
2217 | |||
2218 | // Tx Excessive Collision Packet Counter | ||
2219 | u32 TXcl; // 0x6108 | ||
2220 | |||
2221 | // Tx Total Collision Packet Counter | ||
2222 | u32 TNcl; // 0x610C | ||
2223 | |||
2224 | // Tx Pause Frame Honored Counter | ||
2225 | u32 TPfh; // 0x6110 | ||
2226 | |||
2227 | // Tx Drop Frame Counter | ||
2228 | u32 TDrp; // 0x6114 | ||
2229 | |||
2230 | // Tx Jabber Frame Counter | ||
2231 | u32 TJbr; // 0x6118 | ||
2232 | |||
2233 | // Tx FCS Error Counter | ||
2234 | u32 TFcs; // 0x611C | ||
2235 | |||
2236 | // Tx Control Frame Counter | ||
2237 | u32 TxCf; // 0x6120 | ||
2238 | |||
2239 | // Tx Oversize Frame Counter | ||
2240 | u32 TOvr; // 0x6124 | ||
2241 | |||
2242 | // Tx Undersize Frame Counter | ||
2243 | u32 TUnd; // 0x6128 | ||
2244 | |||
2245 | // Tx Fragments Frame Counter | ||
2246 | u32 TFrg; // 0x612C | ||
2247 | |||
2248 | // Carry Register One Register | ||
2249 | MAC_STAT_REG_1_t Carry1; // 0x6130 | ||
2250 | |||
2251 | // Carry Register Two Register | ||
2252 | MAC_STAT_REG_2_t Carry2; // 0x6134 | ||
2253 | |||
2254 | // Carry Register One Mask Register | ||
2255 | MAC_STAT_REG_1_t Carry1M; // 0x6138 | ||
2256 | |||
2257 | // Carry Register Two Mask Register | ||
2258 | MAC_STAT_REG_2_t Carry2M; // 0x613C | ||
2259 | } MAC_STAT_t, *PMAC_STAT_t; | ||
2260 | |||
2261 | /* END OF MAC STAT REGISTER ADDRESS MAP */ | ||
2262 | |||
2263 | |||
2264 | /* START OF MMC REGISTER ADDRESS MAP */ | ||
2265 | |||
2266 | /* | ||
2267 | * structure for Main Memory Controller Control reg in mmc address map. | ||
2268 | * located at address 0x7000 | ||
2269 | */ | ||
2270 | typedef union _MMC_CTRL_t { | ||
2271 | u32 value; | ||
2272 | struct { | ||
2273 | #ifdef _BIT_FIELDS_HTOL | ||
2274 | u32 reserved:25; // bits 7-31 | ||
2275 | u32 force_ce:1; // bit 6 | ||
2276 | u32 rxdma_disable:1; // bit 5 | ||
2277 | u32 txdma_disable:1; // bit 4 | ||
2278 | u32 txmac_disable:1; // bit 3 | ||
2279 | u32 rxmac_disable:1; // bit 2 | ||
2280 | u32 arb_disable:1; // bit 1 | ||
2281 | u32 mmc_enable:1; // bit 0 | ||
2282 | #else | ||
2283 | u32 mmc_enable:1; // bit 0 | ||
2284 | u32 arb_disable:1; // bit 1 | ||
2285 | u32 rxmac_disable:1; // bit 2 | ||
2286 | u32 txmac_disable:1; // bit 3 | ||
2287 | u32 txdma_disable:1; // bit 4 | ||
2288 | u32 rxdma_disable:1; // bit 5 | ||
2289 | u32 force_ce:1; // bit 6 | ||
2290 | u32 reserved:25; // bits 7-31 | ||
2291 | #endif | ||
2292 | } bits; | ||
2293 | } MMC_CTRL_t, *PMMC_CTRL_t; | ||
2294 | |||
2295 | /* | ||
2296 | * structure for Main Memory Controller Host Memory Access Address reg in mmc | ||
2297 | * address map. Located at address 0x7004 | ||
2298 | */ | ||
2299 | typedef union _MMC_SRAM_ACCESS_t { | ||
2300 | u32 value; | ||
2301 | struct { | ||
2302 | #ifdef _BIT_FIELDS_HTOL | ||
2303 | u32 byte_enable:16; // bits 16-31 | ||
2304 | u32 reserved2:2; // bits 14-15 | ||
2305 | u32 req_addr:10; // bits 4-13 | ||
2306 | u32 reserved1:1; // bit 3 | ||
2307 | u32 is_ctrl_word:1; // bit 2 | ||
2308 | u32 wr_access:1; // bit 1 | ||
2309 | u32 req_access:1; // bit 0 | ||
2310 | #else | ||
2311 | u32 req_access:1; // bit 0 | ||
2312 | u32 wr_access:1; // bit 1 | ||
2313 | u32 is_ctrl_word:1; // bit 2 | ||
2314 | u32 reserved1:1; // bit 3 | ||
2315 | u32 req_addr:10; // bits 4-13 | ||
2316 | u32 reserved2:2; // bits 14-15 | ||
2317 | u32 byte_enable:16; // bits 16-31 | ||
2318 | #endif | ||
2319 | } bits; | ||
2320 | } MMC_SRAM_ACCESS_t, *PMMC_SRAM_ACCESS_t; | ||
2321 | |||
2322 | /* | ||
2323 | * structure for Main Memory Controller Host Memory Access Data reg in mmc | ||
2324 | * address map. Located at address 0x7008 - 0x7014 | ||
2325 | * Defined earlier (u32) | ||
2326 | */ | ||
2327 | |||
2328 | /* | ||
2329 | * Memory Control Module of JAGCore Address Mapping | ||
2330 | */ | ||
2331 | typedef struct _MMC_t { // Location: | ||
2332 | MMC_CTRL_t mmc_ctrl; // 0x7000 | ||
2333 | MMC_SRAM_ACCESS_t sram_access; // 0x7004 | ||
2334 | u32 sram_word1; // 0x7008 | ||
2335 | u32 sram_word2; // 0x700C | ||
2336 | u32 sram_word3; // 0x7010 | ||
2337 | u32 sram_word4; // 0x7014 | ||
2338 | } MMC_t, *PMMC_t; | ||
2339 | |||
2340 | /* END OF MMC REGISTER ADDRESS MAP */ | ||
2341 | |||
2342 | |||
2343 | /* START OF EXP ROM REGISTER ADDRESS MAP */ | ||
2344 | |||
2345 | /* | ||
2346 | * Expansion ROM Module of JAGCore Address Mapping | ||
2347 | */ | ||
2348 | |||
2349 | /* Take this out until it is not empty */ | ||
2350 | #if 0 | ||
2351 | typedef struct _EXP_ROM_t { | ||
2352 | |||
2353 | } EXP_ROM_t, *PEXP_ROM_t; | ||
2354 | #endif | ||
2355 | |||
2356 | /* END OF EXP ROM REGISTER ADDRESS MAP */ | ||
2357 | |||
2358 | |||
2359 | /* | ||
2360 | * JAGCore Address Mapping | ||
2361 | */ | ||
2362 | typedef struct _ADDRESS_MAP_t { | ||
2363 | GLOBAL_t global; | ||
2364 | // unused section of global address map | ||
2365 | u8 unused_global[4096 - sizeof(GLOBAL_t)]; | ||
2366 | TXDMA_t txdma; | ||
2367 | // unused section of txdma address map | ||
2368 | u8 unused_txdma[4096 - sizeof(TXDMA_t)]; | ||
2369 | RXDMA_t rxdma; | ||
2370 | // unused section of rxdma address map | ||
2371 | u8 unused_rxdma[4096 - sizeof(RXDMA_t)]; | ||
2372 | TXMAC_t txmac; | ||
2373 | // unused section of txmac address map | ||
2374 | u8 unused_txmac[4096 - sizeof(TXMAC_t)]; | ||
2375 | RXMAC_t rxmac; | ||
2376 | // unused section of rxmac address map | ||
2377 | u8 unused_rxmac[4096 - sizeof(RXMAC_t)]; | ||
2378 | MAC_t mac; | ||
2379 | // unused section of mac address map | ||
2380 | u8 unused_mac[4096 - sizeof(MAC_t)]; | ||
2381 | MAC_STAT_t macStat; | ||
2382 | // unused section of mac stat address map | ||
2383 | u8 unused_mac_stat[4096 - sizeof(MAC_STAT_t)]; | ||
2384 | MMC_t mmc; | ||
2385 | // unused section of mmc address map | ||
2386 | u8 unused_mmc[4096 - sizeof(MMC_t)]; | ||
2387 | // unused section of address map | ||
2388 | u8 unused_[1015808]; | ||
2389 | |||
2390 | /* Take this out until it is not empty */ | ||
2391 | #if 0 | ||
2392 | EXP_ROM_t exp_rom; | ||
2393 | #endif | ||
2394 | |||
2395 | u8 unused_exp_rom[4096]; // MGS-size TBD | ||
2396 | u8 unused__[524288]; // unused section of address map | ||
2397 | } ADDRESS_MAP_t, *PADDRESS_MAP_t; | ||
2398 | |||
2399 | #endif /* _ET1310_ADDRESS_MAP_H_ */ | ||
diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c new file mode 100644 index 000000000000..c2b194e6a54c --- /dev/null +++ b/drivers/staging/et131x/et1310_eeprom.c | |||
@@ -0,0 +1,480 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_eeprom.c - Code used to access the device's EEPROM | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include "et131x_version.h" | ||
59 | #include "et131x_debug.h" | ||
60 | #include "et131x_defs.h" | ||
61 | |||
62 | #include <linux/pci.h> | ||
63 | #include <linux/init.h> | ||
64 | #include <linux/module.h> | ||
65 | #include <linux/types.h> | ||
66 | #include <linux/kernel.h> | ||
67 | |||
68 | #include <linux/sched.h> | ||
69 | #include <linux/ptrace.h> | ||
70 | #include <linux/slab.h> | ||
71 | #include <linux/ctype.h> | ||
72 | #include <linux/string.h> | ||
73 | #include <linux/timer.h> | ||
74 | #include <linux/interrupt.h> | ||
75 | #include <linux/in.h> | ||
76 | #include <linux/delay.h> | ||
77 | #include <asm/io.h> | ||
78 | #include <asm/system.h> | ||
79 | #include <asm/bitops.h> | ||
80 | |||
81 | #include <linux/netdevice.h> | ||
82 | #include <linux/etherdevice.h> | ||
83 | #include <linux/skbuff.h> | ||
84 | #include <linux/if_arp.h> | ||
85 | #include <linux/ioport.h> | ||
86 | |||
87 | #include "et1310_phy.h" | ||
88 | #include "et1310_pm.h" | ||
89 | #include "et1310_jagcore.h" | ||
90 | #include "et1310_eeprom.h" | ||
91 | |||
92 | #include "et131x_adapter.h" | ||
93 | #include "et131x_initpci.h" | ||
94 | #include "et131x_isr.h" | ||
95 | |||
96 | #include "et1310_tx.h" | ||
97 | |||
98 | |||
99 | /* | ||
100 | * EEPROM Defines | ||
101 | */ | ||
102 | |||
103 | /* LBCIF Register Groups (addressed via 32-bit offsets) */ | ||
104 | #define LBCIF_DWORD0_GROUP_OFFSET 0xAC | ||
105 | #define LBCIF_DWORD1_GROUP_OFFSET 0xB0 | ||
106 | |||
107 | /* LBCIF Registers (addressed via 8-bit offsets) */ | ||
108 | #define LBCIF_ADDRESS_REGISTER_OFFSET 0xAC | ||
109 | #define LBCIF_DATA_REGISTER_OFFSET 0xB0 | ||
110 | #define LBCIF_CONTROL_REGISTER_OFFSET 0xB1 | ||
111 | #define LBCIF_STATUS_REGISTER_OFFSET 0xB2 | ||
112 | |||
113 | /* LBCIF Control Register Bits */ | ||
114 | #define LBCIF_CONTROL_SEQUENTIAL_READ 0x01 | ||
115 | #define LBCIF_CONTROL_PAGE_WRITE 0x02 | ||
116 | #define LBCIF_CONTROL_UNUSED1 0x04 | ||
117 | #define LBCIF_CONTROL_EEPROM_RELOAD 0x08 | ||
118 | #define LBCIF_CONTROL_UNUSED2 0x10 | ||
119 | #define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20 | ||
120 | #define LBCIF_CONTROL_I2C_WRITE 0x40 | ||
121 | #define LBCIF_CONTROL_LBCIF_ENABLE 0x80 | ||
122 | |||
123 | /* LBCIF Status Register Bits */ | ||
124 | #define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01 | ||
125 | #define LBCIF_STATUS_I2C_IDLE 0x02 | ||
126 | #define LBCIF_STATUS_ACK_ERROR 0x04 | ||
127 | #define LBCIF_STATUS_GENERAL_ERROR 0x08 | ||
128 | #define LBCIF_STATUS_UNUSED 0x30 | ||
129 | #define LBCIF_STATUS_CHECKSUM_ERROR 0x40 | ||
130 | #define LBCIF_STATUS_EEPROM_PRESENT 0x80 | ||
131 | |||
132 | /* Miscellaneous Constraints */ | ||
133 | #define MAX_NUM_REGISTER_POLLS 1000 | ||
134 | #define MAX_NUM_WRITE_RETRIES 2 | ||
135 | |||
136 | /* | ||
137 | * Define macros that allow individual register values to be extracted from a | ||
138 | * DWORD1 register grouping | ||
139 | */ | ||
140 | #define EXTRACT_DATA_REGISTER(x) (uint8_t)(x & 0xFF) | ||
141 | #define EXTRACT_STATUS_REGISTER(x) (uint8_t)((x >> 16) & 0xFF) | ||
142 | #define EXTRACT_CONTROL_REG(x) (uint8_t)((x >> 8) & 0xFF) | ||
143 | |||
144 | /** | ||
145 | * EepromWriteByte - Write a byte to the ET1310's EEPROM | ||
146 | * @pAdapter: pointer to our private adapter structure | ||
147 | * @unAddress: the address to write | ||
148 | * @bData: the value to write | ||
149 | * @unEepronId: the ID of the EEPROM | ||
150 | * @unAddressingMode: how the EEPROM is to be accessed | ||
151 | * | ||
152 | * Returns SUCCESS or FAILURE | ||
153 | */ | ||
154 | int32_t EepromWriteByte(struct et131x_adapter *pAdapter, uint32_t unAddress, | ||
155 | uint8_t bData, uint32_t unEepromId, | ||
156 | uint32_t unAddressingMode) | ||
157 | { | ||
158 | struct pci_dev *pdev = pAdapter->pdev; | ||
159 | int32_t nIndex; | ||
160 | int32_t nRetries; | ||
161 | int32_t nError = false; | ||
162 | int32_t nI2CWriteActive = 0; | ||
163 | int32_t nWriteSuccessful = 0; | ||
164 | uint8_t bControl; | ||
165 | uint8_t bStatus = 0; | ||
166 | uint32_t unDword1 = 0; | ||
167 | uint32_t unData = 0; | ||
168 | |||
169 | /* | ||
170 | * The following excerpt is from "Serial EEPROM HW Design | ||
171 | * Specification" Version 0.92 (9/20/2004): | ||
172 | * | ||
173 | * Single Byte Writes | ||
174 | * | ||
175 | * For an EEPROM, an I2C single byte write is defined as a START | ||
176 | * condition followed by the device address, EEPROM address, one byte | ||
177 | * of data and a STOP condition. The STOP condition will trigger the | ||
178 | * EEPROM's internally timed write cycle to the nonvolatile memory. | ||
179 | * All inputs are disabled during this write cycle and the EEPROM will | ||
180 | * not respond to any access until the internal write is complete. | ||
181 | * The steps to execute a single byte write are as follows: | ||
182 | * | ||
183 | * 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and | ||
184 | * bits 7,1:0 both equal to 1, at least once after reset. | ||
185 | * Subsequent operations need only to check that bits 1:0 are | ||
186 | * equal to 1 prior to starting a single byte write. | ||
187 | * | ||
188 | * 2. Write to the LBCIF Control Register: bit 7=1, bit 6=1, bit 3=0, | ||
189 | * and bits 1:0 both =0. Bit 5 should be set according to the | ||
190 | * type of EEPROM being accessed (1=two byte addressing, 0=one | ||
191 | * byte addressing). | ||
192 | * | ||
193 | * 3. Write the address to the LBCIF Address Register. | ||
194 | * | ||
195 | * 4. Write the data to the LBCIF Data Register (the I2C write will | ||
196 | * begin). | ||
197 | * | ||
198 | * 5. Monitor bit 1:0 of the LBCIF Status Register. When bits 1:0 are | ||
199 | * both equal to 1, the I2C write has completed and the internal | ||
200 | * write cycle of the EEPROM is about to start. (bits 1:0 = 01 is | ||
201 | * a legal state while waiting from both equal to 1, but bits | ||
202 | * 1:0 = 10 is invalid and implies that something is broken). | ||
203 | * | ||
204 | * 6. Check bit 3 of the LBCIF Status Register. If equal to 1, an | ||
205 | * error has occurred. | ||
206 | * | ||
207 | * 7. Check bit 2 of the LBCIF Status Register. If equal to 1 an ACK | ||
208 | * error has occurred on the address phase of the write. This | ||
209 | * could be due to an actual hardware failure or the EEPROM may | ||
210 | * still be in its internal write cycle from a previous write. | ||
211 | * This write operation was ignored and must be repeated later. | ||
212 | * | ||
213 | * 8. Set bit 6 of the LBCIF Control Register = 0. If another write is | ||
214 | * required, go to step 1. | ||
215 | */ | ||
216 | |||
217 | /* Step 1: */ | ||
218 | for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) { | ||
219 | /* Read registers grouped in DWORD1 */ | ||
220 | if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET, | ||
221 | &unDword1)) { | ||
222 | nError = 1; | ||
223 | break; | ||
224 | } | ||
225 | |||
226 | bStatus = EXTRACT_STATUS_REGISTER(unDword1); | ||
227 | |||
228 | if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL && | ||
229 | bStatus & LBCIF_STATUS_I2C_IDLE) { | ||
230 | /* bits 1:0 are equal to 1 */ | ||
231 | break; | ||
232 | } | ||
233 | } | ||
234 | |||
235 | if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) { | ||
236 | return FAILURE; | ||
237 | } | ||
238 | |||
239 | /* Step 2: */ | ||
240 | bControl = 0; | ||
241 | bControl |= LBCIF_CONTROL_LBCIF_ENABLE | LBCIF_CONTROL_I2C_WRITE; | ||
242 | |||
243 | if (unAddressingMode == DUAL_BYTE) { | ||
244 | bControl |= LBCIF_CONTROL_TWO_BYTE_ADDR; | ||
245 | } | ||
246 | |||
247 | if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET, | ||
248 | bControl)) { | ||
249 | return FAILURE; | ||
250 | } | ||
251 | |||
252 | nI2CWriteActive = 1; | ||
253 | |||
254 | /* Prepare EEPROM address for Step 3 */ | ||
255 | unAddress |= (unAddressingMode == DUAL_BYTE) ? | ||
256 | (unEepromId << 16) : (unEepromId << 8); | ||
257 | |||
258 | for (nRetries = 0; nRetries < MAX_NUM_WRITE_RETRIES; nRetries++) { | ||
259 | /* Step 3:*/ | ||
260 | if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER_OFFSET, | ||
261 | unAddress)) { | ||
262 | break; | ||
263 | } | ||
264 | |||
265 | /* Step 4: */ | ||
266 | if (pci_write_config_byte(pdev, LBCIF_DATA_REGISTER_OFFSET, | ||
267 | bData)) { | ||
268 | break; | ||
269 | } | ||
270 | |||
271 | /* Step 5: */ | ||
272 | for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) { | ||
273 | /* Read registers grouped in DWORD1 */ | ||
274 | if (pci_read_config_dword(pdev, | ||
275 | LBCIF_DWORD1_GROUP_OFFSET, | ||
276 | &unDword1)) { | ||
277 | nError = 1; | ||
278 | break; | ||
279 | } | ||
280 | |||
281 | bStatus = EXTRACT_STATUS_REGISTER(unDword1); | ||
282 | |||
283 | if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL && | ||
284 | bStatus & LBCIF_STATUS_I2C_IDLE) { | ||
285 | /* I2C write complete */ | ||
286 | break; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) { | ||
291 | break; | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * Step 6: Don't break here if we are revision 1, this is | ||
296 | * so we do a blind write for load bug. | ||
297 | */ | ||
298 | if (bStatus & LBCIF_STATUS_GENERAL_ERROR | ||
299 | && pAdapter->RevisionID == 0) { | ||
300 | break; | ||
301 | } | ||
302 | |||
303 | /* Step 7 */ | ||
304 | if (bStatus & LBCIF_STATUS_ACK_ERROR) { | ||
305 | /* | ||
306 | * This could be due to an actual hardware failure | ||
307 | * or the EEPROM may still be in its internal write | ||
308 | * cycle from a previous write. This write operation | ||
309 | * was ignored and must be repeated later. | ||
310 | */ | ||
311 | udelay(10); | ||
312 | continue; | ||
313 | } | ||
314 | |||
315 | nWriteSuccessful = 1; | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | /* Step 8: */ | ||
320 | udelay(10); | ||
321 | nIndex = 0; | ||
322 | while (nI2CWriteActive) { | ||
323 | bControl &= ~LBCIF_CONTROL_I2C_WRITE; | ||
324 | |||
325 | if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET, | ||
326 | bControl)) { | ||
327 | nWriteSuccessful = 0; | ||
328 | } | ||
329 | |||
330 | /* Do read until internal ACK_ERROR goes away meaning write | ||
331 | * completed | ||
332 | */ | ||
333 | do { | ||
334 | pci_write_config_dword(pdev, | ||
335 | LBCIF_ADDRESS_REGISTER_OFFSET, | ||
336 | unAddress); | ||
337 | do { | ||
338 | pci_read_config_dword(pdev, | ||
339 | LBCIF_DATA_REGISTER_OFFSET, &unData); | ||
340 | } while ((unData & 0x00010000) == 0); | ||
341 | } while (unData & 0x00040000); | ||
342 | |||
343 | bControl = EXTRACT_CONTROL_REG(unData); | ||
344 | |||
345 | if (bControl != 0xC0 || nIndex == 10000) { | ||
346 | break; | ||
347 | } | ||
348 | |||
349 | nIndex++; | ||
350 | } | ||
351 | |||
352 | return nWriteSuccessful ? SUCCESS : FAILURE; | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * EepromReadByte - Read a byte from the ET1310's EEPROM | ||
357 | * @pAdapter: pointer to our private adapter structure | ||
358 | * @unAddress: the address from which to read | ||
359 | * @pbData: a pointer to a byte in which to store the value of the read | ||
360 | * @unEepronId: the ID of the EEPROM | ||
361 | * @unAddressingMode: how the EEPROM is to be accessed | ||
362 | * | ||
363 | * Returns SUCCESS or FAILURE | ||
364 | */ | ||
365 | int32_t EepromReadByte(struct et131x_adapter *pAdapter, uint32_t unAddress, | ||
366 | uint8_t *pbData, uint32_t unEepromId, | ||
367 | uint32_t unAddressingMode) | ||
368 | { | ||
369 | struct pci_dev *pdev = pAdapter->pdev; | ||
370 | int32_t nIndex; | ||
371 | int32_t nError = 0; | ||
372 | uint8_t bControl; | ||
373 | uint8_t bStatus = 0; | ||
374 | uint32_t unDword1 = 0; | ||
375 | |||
376 | /* | ||
377 | * The following excerpt is from "Serial EEPROM HW Design | ||
378 | * Specification" Version 0.92 (9/20/2004): | ||
379 | * | ||
380 | * Single Byte Reads | ||
381 | * | ||
382 | * A single byte read is similar to the single byte write, with the | ||
383 | * exception of the data flow: | ||
384 | * | ||
385 | * 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and | ||
386 | * bits 7,1:0 both equal to 1, at least once after reset. | ||
387 | * Subsequent operations need only to check that bits 1:0 are equal | ||
388 | * to 1 prior to starting a single byte read. | ||
389 | * | ||
390 | * 2. Write to the LBCIF Control Register: bit 7=1, bit 6=0, bit 3=0, | ||
391 | * and bits 1:0 both =0. Bit 5 should be set according to the type | ||
392 | * of EEPROM being accessed (1=two byte addressing, 0=one byte | ||
393 | * addressing). | ||
394 | * | ||
395 | * 3. Write the address to the LBCIF Address Register (I2C read will | ||
396 | * begin). | ||
397 | * | ||
398 | * 4. Monitor bit 0 of the LBCIF Status Register. When =1, I2C read | ||
399 | * is complete. (if bit 1 =1 and bit 0 stays =0, a hardware failure | ||
400 | * has occurred). | ||
401 | * | ||
402 | * 5. Check bit 2 of the LBCIF Status Register. If =1, then an error | ||
403 | * has occurred. The data that has been returned from the PHY may | ||
404 | * be invalid. | ||
405 | * | ||
406 | * 6. Regardless of error status, read data byte from LBCIF Data | ||
407 | * Register. If another byte is required, go to step 1. | ||
408 | */ | ||
409 | |||
410 | /* Step 1: */ | ||
411 | for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) { | ||
412 | /* Read registers grouped in DWORD1 */ | ||
413 | if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET, | ||
414 | &unDword1)) { | ||
415 | nError = 1; | ||
416 | break; | ||
417 | } | ||
418 | |||
419 | bStatus = EXTRACT_STATUS_REGISTER(unDword1); | ||
420 | |||
421 | if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL && | ||
422 | bStatus & LBCIF_STATUS_I2C_IDLE) { | ||
423 | /* bits 1:0 are equal to 1 */ | ||
424 | break; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) { | ||
429 | return FAILURE; | ||
430 | } | ||
431 | |||
432 | /* Step 2: */ | ||
433 | bControl = 0; | ||
434 | bControl |= LBCIF_CONTROL_LBCIF_ENABLE; | ||
435 | |||
436 | if (unAddressingMode == DUAL_BYTE) { | ||
437 | bControl |= LBCIF_CONTROL_TWO_BYTE_ADDR; | ||
438 | } | ||
439 | |||
440 | if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET, | ||
441 | bControl)) { | ||
442 | return FAILURE; | ||
443 | } | ||
444 | |||
445 | /* Step 3: */ | ||
446 | unAddress |= (unAddressingMode == DUAL_BYTE) ? | ||
447 | (unEepromId << 16) : (unEepromId << 8); | ||
448 | |||
449 | if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER_OFFSET, | ||
450 | unAddress)) { | ||
451 | return FAILURE; | ||
452 | } | ||
453 | |||
454 | /* Step 4: */ | ||
455 | for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) { | ||
456 | /* Read registers grouped in DWORD1 */ | ||
457 | if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET, | ||
458 | &unDword1)) { | ||
459 | nError = 1; | ||
460 | break; | ||
461 | } | ||
462 | |||
463 | bStatus = EXTRACT_STATUS_REGISTER(unDword1); | ||
464 | |||
465 | if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL | ||
466 | && bStatus & LBCIF_STATUS_I2C_IDLE) { | ||
467 | /* I2C read complete */ | ||
468 | break; | ||
469 | } | ||
470 | } | ||
471 | |||
472 | if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) { | ||
473 | return FAILURE; | ||
474 | } | ||
475 | |||
476 | /* Step 6: */ | ||
477 | *pbData = EXTRACT_DATA_REGISTER(unDword1); | ||
478 | |||
479 | return (bStatus & LBCIF_STATUS_ACK_ERROR) ? FAILURE : SUCCESS; | ||
480 | } | ||
diff --git a/drivers/staging/et131x/et1310_eeprom.h b/drivers/staging/et131x/et1310_eeprom.h new file mode 100644 index 000000000000..9b6f8ad77b49 --- /dev/null +++ b/drivers/staging/et131x/et1310_eeprom.h | |||
@@ -0,0 +1,89 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_eeprom.h - Defines, structs, enums, prototypes, etc. used for EEPROM | ||
12 | * access routines | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef __ET1310_EEPROM_H__ | ||
60 | #define __ET1310_EEPROM_H__ | ||
61 | |||
62 | #include "et1310_address_map.h" | ||
63 | |||
64 | #ifndef SUCCESS | ||
65 | #define SUCCESS 0 | ||
66 | #define FAILURE 1 | ||
67 | #endif | ||
68 | |||
69 | #ifndef READ | ||
70 | #define READ 0 | ||
71 | #define WRITE 1 | ||
72 | #endif | ||
73 | |||
74 | #ifndef SINGLE_BYTE | ||
75 | #define SINGLE_BYTE 0 | ||
76 | #define DUAL_BYTE 1 | ||
77 | #endif | ||
78 | |||
79 | /* Forward declaration of the private adapter structure */ | ||
80 | struct et131x_adapter; | ||
81 | |||
82 | int32_t EepromWriteByte(struct et131x_adapter *adapter, u32 unAddress, | ||
83 | u8 bData, u32 unEepromId, | ||
84 | u32 unAddressingMode); | ||
85 | int32_t EepromReadByte(struct et131x_adapter *adapter, u32 unAddress, | ||
86 | u8 *pbData, u32 unEepromId, | ||
87 | u32 unAddressingMode); | ||
88 | |||
89 | #endif /* _ET1310_EEPROM_H_ */ | ||
diff --git a/drivers/staging/et131x/et1310_jagcore.c b/drivers/staging/et131x/et1310_jagcore.c new file mode 100644 index 000000000000..993b30ea71e2 --- /dev/null +++ b/drivers/staging/et131x/et1310_jagcore.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_jagcore.c - All code pertaining to the ET1301/ET131x's JAGcore | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include "et131x_version.h" | ||
59 | #include "et131x_debug.h" | ||
60 | #include "et131x_defs.h" | ||
61 | |||
62 | #include <linux/init.h> | ||
63 | #include <linux/module.h> | ||
64 | #include <linux/types.h> | ||
65 | #include <linux/kernel.h> | ||
66 | |||
67 | #include <linux/sched.h> | ||
68 | #include <linux/ptrace.h> | ||
69 | #include <linux/slab.h> | ||
70 | #include <linux/ctype.h> | ||
71 | #include <linux/string.h> | ||
72 | #include <linux/timer.h> | ||
73 | #include <linux/interrupt.h> | ||
74 | #include <linux/in.h> | ||
75 | #include <linux/delay.h> | ||
76 | #include <asm/io.h> | ||
77 | #include <asm/system.h> | ||
78 | #include <asm/bitops.h> | ||
79 | |||
80 | #include <linux/netdevice.h> | ||
81 | #include <linux/etherdevice.h> | ||
82 | #include <linux/skbuff.h> | ||
83 | #include <linux/if_arp.h> | ||
84 | #include <linux/ioport.h> | ||
85 | |||
86 | #include "et1310_phy.h" | ||
87 | #include "et1310_pm.h" | ||
88 | #include "et1310_jagcore.h" | ||
89 | |||
90 | #include "et131x_adapter.h" | ||
91 | #include "et131x_initpci.h" | ||
92 | |||
93 | /* Data for debugging facilities */ | ||
94 | #ifdef CONFIG_ET131X_DEBUG | ||
95 | extern dbg_info_t *et131x_dbginfo; | ||
96 | #endif /* CONFIG_ET131X_DEBUG */ | ||
97 | |||
98 | /** | ||
99 | * ConfigGlobalRegs - Used to configure the global registers on the JAGCore | ||
100 | * @pAdpater: pointer to our adapter structure | ||
101 | */ | ||
102 | void ConfigGlobalRegs(struct et131x_adapter *pAdapter) | ||
103 | { | ||
104 | struct _GLOBAL_t __iomem *pGbl = &pAdapter->CSRAddress->global; | ||
105 | |||
106 | DBG_ENTER(et131x_dbginfo); | ||
107 | |||
108 | if (pAdapter->RegistryPhyLoopbk == false) { | ||
109 | if (pAdapter->RegistryJumboPacket < 2048) { | ||
110 | /* Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word | ||
111 | * block of RAM that the driver can split between Tx | ||
112 | * and Rx as it desires. Our default is to split it | ||
113 | * 50/50: | ||
114 | */ | ||
115 | writel(0, &pGbl->rxq_start_addr.value); | ||
116 | writel(pAdapter->RegistryRxMemEnd, | ||
117 | &pGbl->rxq_end_addr.value); | ||
118 | writel(pAdapter->RegistryRxMemEnd + 1, | ||
119 | &pGbl->txq_start_addr.value); | ||
120 | writel(INTERNAL_MEM_SIZE - 1, | ||
121 | &pGbl->txq_end_addr.value); | ||
122 | } else if (pAdapter->RegistryJumboPacket < 8192) { | ||
123 | /* For jumbo packets > 2k but < 8k, split 50-50. */ | ||
124 | writel(0, &pGbl->rxq_start_addr.value); | ||
125 | writel(INTERNAL_MEM_RX_OFFSET, | ||
126 | &pGbl->rxq_end_addr.value); | ||
127 | writel(INTERNAL_MEM_RX_OFFSET + 1, | ||
128 | &pGbl->txq_start_addr.value); | ||
129 | writel(INTERNAL_MEM_SIZE - 1, | ||
130 | &pGbl->txq_end_addr.value); | ||
131 | } else { | ||
132 | /* 9216 is the only packet size greater than 8k that | ||
133 | * is available. The Tx buffer has to be big enough | ||
134 | * for one whole packet on the Tx side. We'll make | ||
135 | * the Tx 9408, and give the rest to Rx | ||
136 | */ | ||
137 | writel(0x0000, &pGbl->rxq_start_addr.value); | ||
138 | writel(0x01b3, &pGbl->rxq_end_addr.value); | ||
139 | writel(0x01b4, &pGbl->txq_start_addr.value); | ||
140 | writel(INTERNAL_MEM_SIZE - 1, | ||
141 | &pGbl->txq_end_addr.value); | ||
142 | } | ||
143 | |||
144 | /* Initialize the loopback register. Disable all loopbacks. */ | ||
145 | writel(0, &pGbl->loopback.value); | ||
146 | } else { | ||
147 | /* For PHY Line loopback, the memory is configured as if Tx | ||
148 | * and Rx both have all the memory. This is because the | ||
149 | * RxMAC will write data into the space, and the TxMAC will | ||
150 | * read it out. | ||
151 | */ | ||
152 | writel(0, &pGbl->rxq_start_addr.value); | ||
153 | writel(INTERNAL_MEM_SIZE - 1, &pGbl->rxq_end_addr.value); | ||
154 | writel(0, &pGbl->txq_start_addr.value); | ||
155 | writel(INTERNAL_MEM_SIZE - 1, &pGbl->txq_end_addr.value); | ||
156 | |||
157 | /* Initialize the loopback register (MAC loopback). */ | ||
158 | writel(1, &pGbl->loopback.value); | ||
159 | } | ||
160 | |||
161 | /* MSI Register */ | ||
162 | writel(0, &pGbl->msi_config.value); | ||
163 | |||
164 | /* By default, disable the watchdog timer. It will be enabled when | ||
165 | * a packet is queued. | ||
166 | */ | ||
167 | writel(0, &pGbl->watchdog_timer); | ||
168 | |||
169 | DBG_LEAVE(et131x_dbginfo); | ||
170 | } | ||
171 | |||
172 | /** | ||
173 | * ConfigMMCRegs - Used to configure the main memory registers in the JAGCore | ||
174 | * @pAdapter: pointer to our adapter structure | ||
175 | */ | ||
176 | void ConfigMMCRegs(struct et131x_adapter *pAdapter) | ||
177 | { | ||
178 | MMC_CTRL_t mmc_ctrl = { 0 }; | ||
179 | |||
180 | DBG_ENTER(et131x_dbginfo); | ||
181 | |||
182 | /* All we need to do is initialize the Memory Control Register */ | ||
183 | mmc_ctrl.bits.force_ce = 0x0; | ||
184 | mmc_ctrl.bits.rxdma_disable = 0x0; | ||
185 | mmc_ctrl.bits.txdma_disable = 0x0; | ||
186 | mmc_ctrl.bits.txmac_disable = 0x0; | ||
187 | mmc_ctrl.bits.rxmac_disable = 0x0; | ||
188 | mmc_ctrl.bits.arb_disable = 0x0; | ||
189 | mmc_ctrl.bits.mmc_enable = 0x1; | ||
190 | |||
191 | writel(mmc_ctrl.value, &pAdapter->CSRAddress->mmc.mmc_ctrl.value); | ||
192 | |||
193 | DBG_LEAVE(et131x_dbginfo); | ||
194 | } | ||
195 | |||
196 | void et131x_enable_interrupts(struct et131x_adapter *adapter) | ||
197 | { | ||
198 | uint32_t MaskValue; | ||
199 | |||
200 | /* Enable all global interrupts */ | ||
201 | if ((adapter->FlowControl == TxOnly) || (adapter->FlowControl == Both)) { | ||
202 | MaskValue = INT_MASK_ENABLE; | ||
203 | } else { | ||
204 | MaskValue = INT_MASK_ENABLE_NO_FLOW; | ||
205 | } | ||
206 | |||
207 | if (adapter->DriverNoPhyAccess) { | ||
208 | MaskValue |= 0x10000; | ||
209 | } | ||
210 | |||
211 | adapter->CachedMaskValue.value = MaskValue; | ||
212 | writel(MaskValue, &adapter->CSRAddress->global.int_mask.value); | ||
213 | } | ||
214 | |||
215 | void et131x_disable_interrupts(struct et131x_adapter * adapter) | ||
216 | { | ||
217 | /* Disable all global interrupts */ | ||
218 | adapter->CachedMaskValue.value = INT_MASK_DISABLE; | ||
219 | writel(INT_MASK_DISABLE, &adapter->CSRAddress->global.int_mask.value); | ||
220 | } | ||
diff --git a/drivers/staging/et131x/et1310_jagcore.h b/drivers/staging/et131x/et1310_jagcore.h new file mode 100644 index 000000000000..9fc829336df1 --- /dev/null +++ b/drivers/staging/et131x/et1310_jagcore.h | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_jagcore.h - Defines, structs, enums, prototypes, etc. pertaining to | ||
12 | * the JAGCore | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef __ET1310_JAGCORE_H__ | ||
60 | #define __ET1310_JAGCORE_H__ | ||
61 | |||
62 | #include "et1310_address_map.h" | ||
63 | |||
64 | |||
65 | #define INTERNAL_MEM_SIZE 0x400 //1024 of internal memory | ||
66 | #define INTERNAL_MEM_RX_OFFSET 0x1FF //50% Tx, 50% Rx | ||
67 | |||
68 | #define REGS_MAX_ARRAY 4096 | ||
69 | |||
70 | /* | ||
71 | * For interrupts, normal running is: | ||
72 | * rxdma_xfr_done, phy_interrupt, mac_stat_interrupt, | ||
73 | * watchdog_interrupt & txdma_xfer_done | ||
74 | * | ||
75 | * In both cases, when flow control is enabled for either Tx or bi-direction, | ||
76 | * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the | ||
77 | * buffer rings are running low. | ||
78 | */ | ||
79 | #define INT_MASK_DISABLE 0xffffffff | ||
80 | |||
81 | // NOTE: Masking out MAC_STAT Interrupt for now... | ||
82 | //#define INT_MASK_ENABLE 0xfff6bf17 | ||
83 | //#define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7 | ||
84 | #define INT_MASK_ENABLE 0xfffebf17 | ||
85 | #define INT_MASK_ENABLE_NO_FLOW 0xfffebfd7 | ||
86 | |||
87 | /* DATA STRUCTURES FOR DIRECT REGISTER ACCESS */ | ||
88 | |||
89 | typedef struct { | ||
90 | u8 bReadWrite; | ||
91 | u32 nRegCount; | ||
92 | u32 nData[REGS_MAX_ARRAY]; | ||
93 | u32 nOffsets[REGS_MAX_ARRAY]; | ||
94 | } JAGCORE_ACCESS_REGS, *PJAGCORE_ACCESS_REGS; | ||
95 | |||
96 | typedef struct { | ||
97 | u8 bReadWrite; | ||
98 | u32 nDataWidth; | ||
99 | u32 nRegCount; | ||
100 | u32 nOffsets[REGS_MAX_ARRAY]; | ||
101 | u32 nData[REGS_MAX_ARRAY]; | ||
102 | } PCI_CFG_SPACE_REGS, *PPCI_CFG_SPACE_REGS; | ||
103 | |||
104 | /* Forward declaration of the private adapter structure */ | ||
105 | struct et131x_adapter; | ||
106 | |||
107 | void ConfigGlobalRegs(struct et131x_adapter *pAdapter); | ||
108 | void ConfigMMCRegs(struct et131x_adapter *pAdapter); | ||
109 | void et131x_enable_interrupts(struct et131x_adapter *adapter); | ||
110 | void et131x_disable_interrupts(struct et131x_adapter *adapter); | ||
111 | |||
112 | #endif /* __ET1310_JAGCORE_H__ */ | ||
diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c new file mode 100644 index 000000000000..1924968ab24f --- /dev/null +++ b/drivers/staging/et131x/et1310_mac.c | |||
@@ -0,0 +1,792 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_mac.c - All code and routines pertaining to the MAC | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include "et131x_version.h" | ||
59 | #include "et131x_debug.h" | ||
60 | #include "et131x_defs.h" | ||
61 | |||
62 | #include <linux/init.h> | ||
63 | #include <linux/module.h> | ||
64 | #include <linux/types.h> | ||
65 | #include <linux/kernel.h> | ||
66 | |||
67 | #include <linux/sched.h> | ||
68 | #include <linux/ptrace.h> | ||
69 | #include <linux/slab.h> | ||
70 | #include <linux/ctype.h> | ||
71 | #include <linux/string.h> | ||
72 | #include <linux/timer.h> | ||
73 | #include <linux/interrupt.h> | ||
74 | #include <linux/in.h> | ||
75 | #include <linux/delay.h> | ||
76 | #include <asm/io.h> | ||
77 | #include <asm/system.h> | ||
78 | #include <asm/bitops.h> | ||
79 | |||
80 | #include <linux/netdevice.h> | ||
81 | #include <linux/etherdevice.h> | ||
82 | #include <linux/skbuff.h> | ||
83 | #include <linux/if_arp.h> | ||
84 | #include <linux/ioport.h> | ||
85 | #include <linux/crc32.h> | ||
86 | |||
87 | #include "et1310_phy.h" | ||
88 | #include "et1310_pm.h" | ||
89 | #include "et1310_jagcore.h" | ||
90 | #include "et1310_mac.h" | ||
91 | |||
92 | #include "et131x_adapter.h" | ||
93 | #include "et131x_initpci.h" | ||
94 | |||
95 | /* Data for debugging facilities */ | ||
96 | #ifdef CONFIG_ET131X_DEBUG | ||
97 | extern dbg_info_t *et131x_dbginfo; | ||
98 | #endif /* CONFIG_ET131X_DEBUG */ | ||
99 | |||
100 | /** | ||
101 | * ConfigMacRegs1 - Initialize the first part of MAC regs | ||
102 | * @pAdpater: pointer to our adapter structure | ||
103 | */ | ||
104 | void ConfigMACRegs1(struct et131x_adapter *pAdapter) | ||
105 | { | ||
106 | struct _MAC_t __iomem *pMac = &pAdapter->CSRAddress->mac; | ||
107 | MAC_STATION_ADDR1_t station1; | ||
108 | MAC_STATION_ADDR2_t station2; | ||
109 | MAC_IPG_t ipg; | ||
110 | MAC_HFDP_t hfdp; | ||
111 | MII_MGMT_CFG_t mii_mgmt_cfg; | ||
112 | |||
113 | DBG_ENTER(et131x_dbginfo); | ||
114 | |||
115 | /* First we need to reset everything. Write to MAC configuration | ||
116 | * register 1 to perform reset. | ||
117 | */ | ||
118 | writel(0xC00F0000, &pMac->cfg1.value); | ||
119 | |||
120 | /* Next lets configure the MAC Inter-packet gap register */ | ||
121 | ipg.bits.non_B2B_ipg_1 = 0x38; // 58d | ||
122 | ipg.bits.non_B2B_ipg_2 = 0x58; // 88d | ||
123 | ipg.bits.min_ifg_enforce = 0x50; // 80d | ||
124 | ipg.bits.B2B_ipg = 0x60; // 96d | ||
125 | writel(ipg.value, &pMac->ipg.value); | ||
126 | |||
127 | /* Next lets configure the MAC Half Duplex register */ | ||
128 | hfdp.bits.alt_beb_trunc = 0xA; | ||
129 | hfdp.bits.alt_beb_enable = 0x0; | ||
130 | hfdp.bits.bp_no_backoff = 0x0; | ||
131 | hfdp.bits.no_backoff = 0x0; | ||
132 | hfdp.bits.excess_defer = 0x1; | ||
133 | hfdp.bits.rexmit_max = 0xF; | ||
134 | hfdp.bits.coll_window = 0x37; // 55d | ||
135 | writel(hfdp.value, &pMac->hfdp.value); | ||
136 | |||
137 | /* Next lets configure the MAC Interface Control register */ | ||
138 | writel(0, &pMac->if_ctrl.value); | ||
139 | |||
140 | /* Let's move on to setting up the mii managment configuration */ | ||
141 | mii_mgmt_cfg.bits.reset_mii_mgmt = 0; | ||
142 | mii_mgmt_cfg.bits.scan_auto_incremt = 0; | ||
143 | mii_mgmt_cfg.bits.preamble_suppress = 0; | ||
144 | mii_mgmt_cfg.bits.mgmt_clk_reset = 0x7; | ||
145 | writel(mii_mgmt_cfg.value, &pMac->mii_mgmt_cfg.value); | ||
146 | |||
147 | /* Next lets configure the MAC Station Address register. These | ||
148 | * values are read from the EEPROM during initialization and stored | ||
149 | * in the adapter structure. We write what is stored in the adapter | ||
150 | * structure to the MAC Station Address registers high and low. This | ||
151 | * station address is used for generating and checking pause control | ||
152 | * packets. | ||
153 | */ | ||
154 | station2.bits.Octet1 = pAdapter->CurrentAddress[0]; | ||
155 | station2.bits.Octet2 = pAdapter->CurrentAddress[1]; | ||
156 | station1.bits.Octet3 = pAdapter->CurrentAddress[2]; | ||
157 | station1.bits.Octet4 = pAdapter->CurrentAddress[3]; | ||
158 | station1.bits.Octet5 = pAdapter->CurrentAddress[4]; | ||
159 | station1.bits.Octet6 = pAdapter->CurrentAddress[5]; | ||
160 | writel(station1.value, &pMac->station_addr_1.value); | ||
161 | writel(station2.value, &pMac->station_addr_2.value); | ||
162 | |||
163 | /* Max ethernet packet in bytes that will passed by the mac without | ||
164 | * being truncated. Allow the MAC to pass 4 more than our max packet | ||
165 | * size. This is 4 for the Ethernet CRC. | ||
166 | * | ||
167 | * Packets larger than (RegistryJumboPacket) that do not contain a | ||
168 | * VLAN ID will be dropped by the Rx function. | ||
169 | */ | ||
170 | writel(pAdapter->RegistryJumboPacket + 4, &pMac->max_fm_len.value); | ||
171 | |||
172 | /* clear out MAC config reset */ | ||
173 | writel(0, &pMac->cfg1.value); | ||
174 | |||
175 | DBG_LEAVE(et131x_dbginfo); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * ConfigMacRegs2 - Initialize the second part of MAC regs | ||
180 | * @pAdpater: pointer to our adapter structure | ||
181 | */ | ||
182 | void ConfigMACRegs2(struct et131x_adapter *pAdapter) | ||
183 | { | ||
184 | int32_t delay = 0; | ||
185 | struct _MAC_t __iomem *pMac = &pAdapter->CSRAddress->mac; | ||
186 | MAC_CFG1_t cfg1; | ||
187 | MAC_CFG2_t cfg2; | ||
188 | MAC_IF_CTRL_t ifctrl; | ||
189 | TXMAC_CTL_t ctl; | ||
190 | |||
191 | DBG_ENTER(et131x_dbginfo); | ||
192 | |||
193 | ctl.value = readl(&pAdapter->CSRAddress->txmac.ctl.value); | ||
194 | cfg1.value = readl(&pMac->cfg1.value); | ||
195 | cfg2.value = readl(&pMac->cfg2.value); | ||
196 | ifctrl.value = readl(&pMac->if_ctrl.value); | ||
197 | |||
198 | if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) { | ||
199 | cfg2.bits.if_mode = 0x2; | ||
200 | ifctrl.bits.phy_mode = 0x0; | ||
201 | } else { | ||
202 | cfg2.bits.if_mode = 0x1; | ||
203 | ifctrl.bits.phy_mode = 0x1; | ||
204 | } | ||
205 | |||
206 | /* We need to enable Rx/Tx */ | ||
207 | cfg1.bits.rx_enable = 0x1; | ||
208 | cfg1.bits.tx_enable = 0x1; | ||
209 | |||
210 | /* Set up flow control */ | ||
211 | cfg1.bits.tx_flow = 0x1; | ||
212 | |||
213 | if ((pAdapter->FlowControl == RxOnly) || | ||
214 | (pAdapter->FlowControl == Both)) { | ||
215 | cfg1.bits.rx_flow = 0x1; | ||
216 | } else { | ||
217 | cfg1.bits.rx_flow = 0x0; | ||
218 | } | ||
219 | |||
220 | /* Initialize loop back to off */ | ||
221 | cfg1.bits.loop_back = 0; | ||
222 | |||
223 | writel(cfg1.value, &pMac->cfg1.value); | ||
224 | |||
225 | /* Now we need to initialize the MAC Configuration 2 register */ | ||
226 | cfg2.bits.preamble_len = 0x7; | ||
227 | cfg2.bits.huge_frame = 0x0; | ||
228 | /* LENGTH FIELD CHECKING bit4: Set this bit to cause the MAC to check | ||
229 | * the frame's length field to ensure it matches the actual data | ||
230 | * field length. Clear this bit if no length field checking is | ||
231 | * desired. Its default is 0. | ||
232 | */ | ||
233 | cfg2.bits.len_check = 0x1; | ||
234 | |||
235 | if (pAdapter->RegistryPhyLoopbk == false) { | ||
236 | cfg2.bits.pad_crc = 0x1; | ||
237 | cfg2.bits.crc_enable = 0x1; | ||
238 | } else { | ||
239 | cfg2.bits.pad_crc = 0; | ||
240 | cfg2.bits.crc_enable = 0; | ||
241 | } | ||
242 | |||
243 | /* 1 - full duplex, 0 - half-duplex */ | ||
244 | cfg2.bits.full_duplex = pAdapter->uiDuplexMode; | ||
245 | ifctrl.bits.ghd_mode = !pAdapter->uiDuplexMode; | ||
246 | |||
247 | writel(ifctrl.value, &pMac->if_ctrl.value); | ||
248 | writel(cfg2.value, &pMac->cfg2.value); | ||
249 | |||
250 | do { | ||
251 | udelay(10); | ||
252 | delay++; | ||
253 | cfg1.value = readl(&pMac->cfg1.value); | ||
254 | } while ((!cfg1.bits.syncd_rx_en || | ||
255 | !cfg1.bits.syncd_tx_en) && | ||
256 | delay < 100); | ||
257 | |||
258 | if (delay == 100) { | ||
259 | DBG_ERROR(et131x_dbginfo, | ||
260 | "Syncd bits did not respond correctly cfg1 word 0x%08x\n", | ||
261 | cfg1.value); | ||
262 | } | ||
263 | |||
264 | DBG_TRACE(et131x_dbginfo, | ||
265 | "Speed %d, Dup %d, CFG1 0x%08x, CFG2 0x%08x, if_ctrl 0x%08x\n", | ||
266 | pAdapter->uiLinkSpeed, pAdapter->uiDuplexMode, | ||
267 | readl(&pMac->cfg1.value), readl(&pMac->cfg2.value), | ||
268 | readl(&pMac->if_ctrl.value)); | ||
269 | |||
270 | /* Enable TXMAC */ | ||
271 | ctl.bits.txmac_en = 0x1; | ||
272 | ctl.bits.fc_disable = 0x1; | ||
273 | writel(ctl.value, &pAdapter->CSRAddress->txmac.ctl.value); | ||
274 | |||
275 | /* Ready to start the RXDMA/TXDMA engine */ | ||
276 | if (!MP_TEST_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER)) { | ||
277 | et131x_rx_dma_enable(pAdapter); | ||
278 | et131x_tx_dma_enable(pAdapter); | ||
279 | } else { | ||
280 | DBG_WARNING(et131x_dbginfo, | ||
281 | "Didn't enable Rx/Tx due to low-power mode\n"); | ||
282 | } | ||
283 | |||
284 | DBG_LEAVE(et131x_dbginfo); | ||
285 | } | ||
286 | |||
287 | void ConfigRxMacRegs(struct et131x_adapter *pAdapter) | ||
288 | { | ||
289 | struct _RXMAC_t __iomem *pRxMac = &pAdapter->CSRAddress->rxmac; | ||
290 | RXMAC_WOL_SA_LO_t sa_lo; | ||
291 | RXMAC_WOL_SA_HI_t sa_hi; | ||
292 | RXMAC_PF_CTRL_t pf_ctrl = { 0 }; | ||
293 | |||
294 | DBG_ENTER(et131x_dbginfo); | ||
295 | |||
296 | /* Disable the MAC while it is being configured (also disable WOL) */ | ||
297 | writel(0x8, &pRxMac->ctrl.value); | ||
298 | |||
299 | /* Initialize WOL to disabled. */ | ||
300 | writel(0, &pRxMac->crc0.value); | ||
301 | writel(0, &pRxMac->crc12.value); | ||
302 | writel(0, &pRxMac->crc34.value); | ||
303 | |||
304 | /* We need to set the WOL mask0 - mask4 next. We initialize it to | ||
305 | * its default Values of 0x00000000 because there are not WOL masks | ||
306 | * as of this time. | ||
307 | */ | ||
308 | writel(0, &pRxMac->mask0_word0); | ||
309 | writel(0, &pRxMac->mask0_word1); | ||
310 | writel(0, &pRxMac->mask0_word2); | ||
311 | writel(0, &pRxMac->mask0_word3); | ||
312 | |||
313 | writel(0, &pRxMac->mask1_word0); | ||
314 | writel(0, &pRxMac->mask1_word1); | ||
315 | writel(0, &pRxMac->mask1_word2); | ||
316 | writel(0, &pRxMac->mask1_word3); | ||
317 | |||
318 | writel(0, &pRxMac->mask2_word0); | ||
319 | writel(0, &pRxMac->mask2_word1); | ||
320 | writel(0, &pRxMac->mask2_word2); | ||
321 | writel(0, &pRxMac->mask2_word3); | ||
322 | |||
323 | writel(0, &pRxMac->mask3_word0); | ||
324 | writel(0, &pRxMac->mask3_word1); | ||
325 | writel(0, &pRxMac->mask3_word2); | ||
326 | writel(0, &pRxMac->mask3_word3); | ||
327 | |||
328 | writel(0, &pRxMac->mask4_word0); | ||
329 | writel(0, &pRxMac->mask4_word1); | ||
330 | writel(0, &pRxMac->mask4_word2); | ||
331 | writel(0, &pRxMac->mask4_word3); | ||
332 | |||
333 | /* Lets setup the WOL Source Address */ | ||
334 | sa_lo.bits.sa3 = pAdapter->CurrentAddress[2]; | ||
335 | sa_lo.bits.sa4 = pAdapter->CurrentAddress[3]; | ||
336 | sa_lo.bits.sa5 = pAdapter->CurrentAddress[4]; | ||
337 | sa_lo.bits.sa6 = pAdapter->CurrentAddress[5]; | ||
338 | writel(sa_lo.value, &pRxMac->sa_lo.value); | ||
339 | |||
340 | sa_hi.bits.sa1 = pAdapter->CurrentAddress[0]; | ||
341 | sa_hi.bits.sa2 = pAdapter->CurrentAddress[1]; | ||
342 | writel(sa_hi.value, &pRxMac->sa_hi.value); | ||
343 | |||
344 | /* Disable all Packet Filtering */ | ||
345 | writel(0, &pRxMac->pf_ctrl.value); | ||
346 | |||
347 | /* Let's initialize the Unicast Packet filtering address */ | ||
348 | if (pAdapter->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) { | ||
349 | SetupDeviceForUnicast(pAdapter); | ||
350 | pf_ctrl.bits.filter_uni_en = 1; | ||
351 | } else { | ||
352 | writel(0, &pRxMac->uni_pf_addr1.value); | ||
353 | writel(0, &pRxMac->uni_pf_addr2.value); | ||
354 | writel(0, &pRxMac->uni_pf_addr3.value); | ||
355 | } | ||
356 | |||
357 | /* Let's initialize the Multicast hash */ | ||
358 | if (pAdapter->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST) { | ||
359 | pf_ctrl.bits.filter_multi_en = 0; | ||
360 | } else { | ||
361 | pf_ctrl.bits.filter_multi_en = 1; | ||
362 | SetupDeviceForMulticast(pAdapter); | ||
363 | } | ||
364 | |||
365 | /* Runt packet filtering. Didn't work in version A silicon. */ | ||
366 | pf_ctrl.bits.min_pkt_size = NIC_MIN_PACKET_SIZE + 4; | ||
367 | pf_ctrl.bits.filter_frag_en = 1; | ||
368 | |||
369 | if (pAdapter->RegistryJumboPacket > 8192) { | ||
370 | RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; | ||
371 | |||
372 | /* In order to transmit jumbo packets greater than 8k, the | ||
373 | * FIFO between RxMAC and RxDMA needs to be reduced in size | ||
374 | * to (16k - Jumbo packet size). In order to implement this, | ||
375 | * we must use "cut through" mode in the RxMAC, which chops | ||
376 | * packets down into segments which are (max_size * 16). In | ||
377 | * this case we selected 256 bytes, since this is the size of | ||
378 | * the PCI-Express TLP's that the 1310 uses. | ||
379 | */ | ||
380 | mcif_ctrl_max_seg.bits.seg_en = 0x1; | ||
381 | mcif_ctrl_max_seg.bits.fc_en = 0x0; | ||
382 | mcif_ctrl_max_seg.bits.max_size = 0x10; | ||
383 | |||
384 | writel(mcif_ctrl_max_seg.value, | ||
385 | &pRxMac->mcif_ctrl_max_seg.value); | ||
386 | } else { | ||
387 | writel(0, &pRxMac->mcif_ctrl_max_seg.value); | ||
388 | } | ||
389 | |||
390 | /* Initialize the MCIF water marks */ | ||
391 | writel(0, &pRxMac->mcif_water_mark.value); | ||
392 | |||
393 | /* Initialize the MIF control */ | ||
394 | writel(0, &pRxMac->mif_ctrl.value); | ||
395 | |||
396 | /* Initialize the Space Available Register */ | ||
397 | writel(0, &pRxMac->space_avail.value); | ||
398 | |||
399 | /* Initialize the the mif_ctrl register | ||
400 | * bit 3: Receive code error. One or more nibbles were signaled as | ||
401 | * errors during the reception of the packet. Clear this | ||
402 | * bit in Gigabit, set it in 100Mbit. This was derived | ||
403 | * experimentally at UNH. | ||
404 | * bit 4: Receive CRC error. The packet's CRC did not match the | ||
405 | * internally generated CRC. | ||
406 | * bit 5: Receive length check error. Indicates that frame length | ||
407 | * field value in the packet does not match the actual data | ||
408 | * byte length and is not a type field. | ||
409 | * bit 16: Receive frame truncated. | ||
410 | * bit 17: Drop packet enable | ||
411 | */ | ||
412 | if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_100MBPS) { | ||
413 | writel(0x30038, &pRxMac->mif_ctrl.value); | ||
414 | } else { | ||
415 | writel(0x30030, &pRxMac->mif_ctrl.value); | ||
416 | } | ||
417 | |||
418 | /* Finally we initialize RxMac to be enabled & WOL disabled. Packet | ||
419 | * filter is always enabled since it is where the runt packets are | ||
420 | * supposed to be dropped. For version A silicon, runt packet | ||
421 | * dropping doesn't work, so it is disabled in the pf_ctrl register, | ||
422 | * but we still leave the packet filter on. | ||
423 | */ | ||
424 | writel(pf_ctrl.value, &pRxMac->pf_ctrl.value); | ||
425 | writel(0x9, &pRxMac->ctrl.value); | ||
426 | |||
427 | DBG_LEAVE(et131x_dbginfo); | ||
428 | } | ||
429 | |||
430 | void ConfigTxMacRegs(struct et131x_adapter *pAdapter) | ||
431 | { | ||
432 | struct _TXMAC_t __iomem *pTxMac = &pAdapter->CSRAddress->txmac; | ||
433 | TXMAC_CF_PARAM_t Local; | ||
434 | |||
435 | DBG_ENTER(et131x_dbginfo); | ||
436 | |||
437 | /* We need to update the Control Frame Parameters | ||
438 | * cfpt - control frame pause timer set to 64 (0x40) | ||
439 | * cfep - control frame extended pause timer set to 0x0 | ||
440 | */ | ||
441 | if (pAdapter->FlowControl == None) { | ||
442 | writel(0, &pTxMac->cf_param.value); | ||
443 | } else { | ||
444 | Local.bits.cfpt = 0x40; | ||
445 | Local.bits.cfep = 0x0; | ||
446 | writel(Local.value, &pTxMac->cf_param.value); | ||
447 | } | ||
448 | |||
449 | DBG_LEAVE(et131x_dbginfo); | ||
450 | } | ||
451 | |||
452 | void ConfigMacStatRegs(struct et131x_adapter *pAdapter) | ||
453 | { | ||
454 | struct _MAC_STAT_t __iomem *pDevMacStat = | ||
455 | &pAdapter->CSRAddress->macStat; | ||
456 | |||
457 | DBG_ENTER(et131x_dbginfo); | ||
458 | |||
459 | /* Next we need to initialize all the MAC_STAT registers to zero on | ||
460 | * the device. | ||
461 | */ | ||
462 | writel(0, &pDevMacStat->RFcs); | ||
463 | writel(0, &pDevMacStat->RAln); | ||
464 | writel(0, &pDevMacStat->RFlr); | ||
465 | writel(0, &pDevMacStat->RDrp); | ||
466 | writel(0, &pDevMacStat->RCde); | ||
467 | writel(0, &pDevMacStat->ROvr); | ||
468 | writel(0, &pDevMacStat->RFrg); | ||
469 | |||
470 | writel(0, &pDevMacStat->TScl); | ||
471 | writel(0, &pDevMacStat->TDfr); | ||
472 | writel(0, &pDevMacStat->TMcl); | ||
473 | writel(0, &pDevMacStat->TLcl); | ||
474 | writel(0, &pDevMacStat->TNcl); | ||
475 | writel(0, &pDevMacStat->TOvr); | ||
476 | writel(0, &pDevMacStat->TUnd); | ||
477 | |||
478 | /* Unmask any counters that we want to track the overflow of. | ||
479 | * Initially this will be all counters. It may become clear later | ||
480 | * that we do not need to track all counters. | ||
481 | */ | ||
482 | { | ||
483 | MAC_STAT_REG_1_t Carry1M = { 0xffffffff }; | ||
484 | |||
485 | Carry1M.bits.rdrp = 0; | ||
486 | Carry1M.bits.rjbr = 1; | ||
487 | Carry1M.bits.rfrg = 0; | ||
488 | Carry1M.bits.rovr = 0; | ||
489 | Carry1M.bits.rund = 1; | ||
490 | Carry1M.bits.rcse = 1; | ||
491 | Carry1M.bits.rcde = 0; | ||
492 | Carry1M.bits.rflr = 0; | ||
493 | Carry1M.bits.raln = 0; | ||
494 | Carry1M.bits.rxuo = 1; | ||
495 | Carry1M.bits.rxpf = 1; | ||
496 | Carry1M.bits.rxcf = 1; | ||
497 | Carry1M.bits.rbca = 1; | ||
498 | Carry1M.bits.rmca = 1; | ||
499 | Carry1M.bits.rfcs = 0; | ||
500 | Carry1M.bits.rpkt = 1; | ||
501 | Carry1M.bits.rbyt = 1; | ||
502 | Carry1M.bits.trmgv = 1; | ||
503 | Carry1M.bits.trmax = 1; | ||
504 | Carry1M.bits.tr1k = 1; | ||
505 | Carry1M.bits.tr511 = 1; | ||
506 | Carry1M.bits.tr255 = 1; | ||
507 | Carry1M.bits.tr127 = 1; | ||
508 | Carry1M.bits.tr64 = 1; | ||
509 | |||
510 | writel(Carry1M.value, &pDevMacStat->Carry1M.value); | ||
511 | } | ||
512 | |||
513 | { | ||
514 | MAC_STAT_REG_2_t Carry2M = { 0xffffffff }; | ||
515 | |||
516 | Carry2M.bits.tdrp = 1; | ||
517 | Carry2M.bits.tpfh = 1; | ||
518 | Carry2M.bits.tncl = 0; | ||
519 | Carry2M.bits.txcl = 1; | ||
520 | Carry2M.bits.tlcl = 0; | ||
521 | Carry2M.bits.tmcl = 0; | ||
522 | Carry2M.bits.tscl = 0; | ||
523 | Carry2M.bits.tedf = 1; | ||
524 | Carry2M.bits.tdfr = 0; | ||
525 | Carry2M.bits.txpf = 1; | ||
526 | Carry2M.bits.tbca = 1; | ||
527 | Carry2M.bits.tmca = 1; | ||
528 | Carry2M.bits.tpkt = 1; | ||
529 | Carry2M.bits.tbyt = 1; | ||
530 | Carry2M.bits.tfrg = 1; | ||
531 | Carry2M.bits.tund = 0; | ||
532 | Carry2M.bits.tovr = 0; | ||
533 | Carry2M.bits.txcf = 1; | ||
534 | Carry2M.bits.tfcs = 1; | ||
535 | Carry2M.bits.tjbr = 1; | ||
536 | |||
537 | writel(Carry2M.value, &pDevMacStat->Carry2M.value); | ||
538 | } | ||
539 | |||
540 | DBG_LEAVE(et131x_dbginfo); | ||
541 | } | ||
542 | |||
543 | void ConfigFlowControl(struct et131x_adapter * pAdapter) | ||
544 | { | ||
545 | if (pAdapter->uiDuplexMode == 0) { | ||
546 | pAdapter->FlowControl = None; | ||
547 | } else { | ||
548 | char RemotePause, RemoteAsyncPause; | ||
549 | |||
550 | ET1310_PhyAccessMiBit(pAdapter, | ||
551 | TRUEPHY_BIT_READ, 5, 10, &RemotePause); | ||
552 | ET1310_PhyAccessMiBit(pAdapter, | ||
553 | TRUEPHY_BIT_READ, 5, 11, | ||
554 | &RemoteAsyncPause); | ||
555 | |||
556 | if ((RemotePause == TRUEPHY_BIT_SET) && | ||
557 | (RemoteAsyncPause == TRUEPHY_BIT_SET)) { | ||
558 | pAdapter->FlowControl = pAdapter->RegistryFlowControl; | ||
559 | } else if ((RemotePause == TRUEPHY_BIT_SET) && | ||
560 | (RemoteAsyncPause == TRUEPHY_BIT_CLEAR)) { | ||
561 | if (pAdapter->RegistryFlowControl == Both) { | ||
562 | pAdapter->FlowControl = Both; | ||
563 | } else { | ||
564 | pAdapter->FlowControl = None; | ||
565 | } | ||
566 | } else if ((RemotePause == TRUEPHY_BIT_CLEAR) && | ||
567 | (RemoteAsyncPause == TRUEPHY_BIT_CLEAR)) { | ||
568 | pAdapter->FlowControl = None; | ||
569 | } else {/* if (RemotePause == TRUEPHY_CLEAR_BIT && | ||
570 | RemoteAsyncPause == TRUEPHY_SET_BIT) */ | ||
571 | if (pAdapter->RegistryFlowControl == Both) { | ||
572 | pAdapter->FlowControl = RxOnly; | ||
573 | } else { | ||
574 | pAdapter->FlowControl = None; | ||
575 | } | ||
576 | } | ||
577 | } | ||
578 | } | ||
579 | |||
580 | /** | ||
581 | * UpdateMacStatHostCounters - Update the local copy of the statistics | ||
582 | * @pAdapter: pointer to the adapter structure | ||
583 | */ | ||
584 | void UpdateMacStatHostCounters(struct et131x_adapter *pAdapter) | ||
585 | { | ||
586 | struct _ce_stats_t *stats = &pAdapter->Stats; | ||
587 | struct _MAC_STAT_t __iomem *pDevMacStat = | ||
588 | &pAdapter->CSRAddress->macStat; | ||
589 | |||
590 | stats->collisions += readl(&pDevMacStat->TNcl); | ||
591 | stats->first_collision += readl(&pDevMacStat->TScl); | ||
592 | stats->tx_deferred += readl(&pDevMacStat->TDfr); | ||
593 | stats->excessive_collisions += readl(&pDevMacStat->TMcl); | ||
594 | stats->late_collisions += readl(&pDevMacStat->TLcl); | ||
595 | stats->tx_uflo += readl(&pDevMacStat->TUnd); | ||
596 | stats->max_pkt_error += readl(&pDevMacStat->TOvr); | ||
597 | |||
598 | stats->alignment_err += readl(&pDevMacStat->RAln); | ||
599 | stats->crc_err += readl(&pDevMacStat->RCde); | ||
600 | stats->norcvbuf += readl(&pDevMacStat->RDrp); | ||
601 | stats->rx_ov_flow += readl(&pDevMacStat->ROvr); | ||
602 | stats->code_violations += readl(&pDevMacStat->RFcs); | ||
603 | stats->length_err += readl(&pDevMacStat->RFlr); | ||
604 | |||
605 | stats->other_errors += readl(&pDevMacStat->RFrg); | ||
606 | } | ||
607 | |||
608 | /** | ||
609 | * HandleMacStatInterrupt | ||
610 | * @pAdapter: pointer to the adapter structure | ||
611 | * | ||
612 | * One of the MACSTAT counters has wrapped. Update the local copy of | ||
613 | * the statistics held in the adapter structure, checking the "wrap" | ||
614 | * bit for each counter. | ||
615 | */ | ||
616 | void HandleMacStatInterrupt(struct et131x_adapter *pAdapter) | ||
617 | { | ||
618 | MAC_STAT_REG_1_t Carry1; | ||
619 | MAC_STAT_REG_2_t Carry2; | ||
620 | |||
621 | DBG_ENTER(et131x_dbginfo); | ||
622 | |||
623 | /* Read the interrupt bits from the register(s). These are Clear On | ||
624 | * Write. | ||
625 | */ | ||
626 | Carry1.value = readl(&pAdapter->CSRAddress->macStat.Carry1.value); | ||
627 | Carry2.value = readl(&pAdapter->CSRAddress->macStat.Carry2.value); | ||
628 | |||
629 | writel(Carry1.value, &pAdapter->CSRAddress->macStat.Carry1.value); | ||
630 | writel(Carry2.value, &pAdapter->CSRAddress->macStat.Carry2.value); | ||
631 | |||
632 | /* We need to do update the host copy of all the MAC_STAT counters. | ||
633 | * For each counter, check it's overflow bit. If the overflow bit is | ||
634 | * set, then increment the host version of the count by one complete | ||
635 | * revolution of the counter. This routine is called when the counter | ||
636 | * block indicates that one of the counters has wrapped. | ||
637 | */ | ||
638 | if (Carry1.bits.rfcs) { | ||
639 | pAdapter->Stats.code_violations += COUNTER_WRAP_16_BIT; | ||
640 | } | ||
641 | if (Carry1.bits.raln) { | ||
642 | pAdapter->Stats.alignment_err += COUNTER_WRAP_12_BIT; | ||
643 | } | ||
644 | if (Carry1.bits.rflr) { | ||
645 | pAdapter->Stats.length_err += COUNTER_WRAP_16_BIT; | ||
646 | } | ||
647 | if (Carry1.bits.rfrg) { | ||
648 | pAdapter->Stats.other_errors += COUNTER_WRAP_16_BIT; | ||
649 | } | ||
650 | if (Carry1.bits.rcde) { | ||
651 | pAdapter->Stats.crc_err += COUNTER_WRAP_16_BIT; | ||
652 | } | ||
653 | if (Carry1.bits.rovr) { | ||
654 | pAdapter->Stats.rx_ov_flow += COUNTER_WRAP_16_BIT; | ||
655 | } | ||
656 | if (Carry1.bits.rdrp) { | ||
657 | pAdapter->Stats.norcvbuf += COUNTER_WRAP_16_BIT; | ||
658 | } | ||
659 | if (Carry2.bits.tovr) { | ||
660 | pAdapter->Stats.max_pkt_error += COUNTER_WRAP_12_BIT; | ||
661 | } | ||
662 | if (Carry2.bits.tund) { | ||
663 | pAdapter->Stats.tx_uflo += COUNTER_WRAP_12_BIT; | ||
664 | } | ||
665 | if (Carry2.bits.tscl) { | ||
666 | pAdapter->Stats.first_collision += COUNTER_WRAP_12_BIT; | ||
667 | } | ||
668 | if (Carry2.bits.tdfr) { | ||
669 | pAdapter->Stats.tx_deferred += COUNTER_WRAP_12_BIT; | ||
670 | } | ||
671 | if (Carry2.bits.tmcl) { | ||
672 | pAdapter->Stats.excessive_collisions += COUNTER_WRAP_12_BIT; | ||
673 | } | ||
674 | if (Carry2.bits.tlcl) { | ||
675 | pAdapter->Stats.late_collisions += COUNTER_WRAP_12_BIT; | ||
676 | } | ||
677 | if (Carry2.bits.tncl) { | ||
678 | pAdapter->Stats.collisions += COUNTER_WRAP_12_BIT; | ||
679 | } | ||
680 | |||
681 | DBG_LEAVE(et131x_dbginfo); | ||
682 | } | ||
683 | |||
684 | void SetupDeviceForMulticast(struct et131x_adapter *pAdapter) | ||
685 | { | ||
686 | struct _RXMAC_t __iomem *rxmac = &pAdapter->CSRAddress->rxmac; | ||
687 | uint32_t nIndex; | ||
688 | uint32_t result; | ||
689 | uint32_t hash1 = 0; | ||
690 | uint32_t hash2 = 0; | ||
691 | uint32_t hash3 = 0; | ||
692 | uint32_t hash4 = 0; | ||
693 | PM_CSR_t pm_csr; | ||
694 | |||
695 | DBG_ENTER(et131x_dbginfo); | ||
696 | |||
697 | /* If ET131X_PACKET_TYPE_MULTICAST is specified, then we provision | ||
698 | * the multi-cast LIST. If it is NOT specified, (and "ALL" is not | ||
699 | * specified) then we should pass NO multi-cast addresses to the | ||
700 | * driver. | ||
701 | */ | ||
702 | if (pAdapter->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) { | ||
703 | DBG_VERBOSE(et131x_dbginfo, | ||
704 | "MULTICAST flag is set, MCCount: %d\n", | ||
705 | pAdapter->MCAddressCount); | ||
706 | |||
707 | /* Loop through our multicast array and set up the device */ | ||
708 | for (nIndex = 0; nIndex < pAdapter->MCAddressCount; nIndex++) { | ||
709 | DBG_VERBOSE(et131x_dbginfo, | ||
710 | "MCList[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
711 | nIndex, | ||
712 | pAdapter->MCList[nIndex][0], | ||
713 | pAdapter->MCList[nIndex][1], | ||
714 | pAdapter->MCList[nIndex][2], | ||
715 | pAdapter->MCList[nIndex][3], | ||
716 | pAdapter->MCList[nIndex][4], | ||
717 | pAdapter->MCList[nIndex][5]); | ||
718 | |||
719 | result = ether_crc(6, pAdapter->MCList[nIndex]); | ||
720 | |||
721 | result = (result & 0x3F800000) >> 23; | ||
722 | |||
723 | if (result < 32) { | ||
724 | hash1 |= (1 << result); | ||
725 | } else if ((31 < result) && (result < 64)) { | ||
726 | result -= 32; | ||
727 | hash2 |= (1 << result); | ||
728 | } else if ((63 < result) && (result < 96)) { | ||
729 | result -= 64; | ||
730 | hash3 |= (1 << result); | ||
731 | } else { | ||
732 | result -= 96; | ||
733 | hash4 |= (1 << result); | ||
734 | } | ||
735 | } | ||
736 | } | ||
737 | |||
738 | /* Write out the new hash to the device */ | ||
739 | pm_csr.value = readl(&pAdapter->CSRAddress->global.pm_csr.value); | ||
740 | if (pm_csr.bits.pm_phy_sw_coma == 0) { | ||
741 | writel(hash1, &rxmac->multi_hash1); | ||
742 | writel(hash2, &rxmac->multi_hash2); | ||
743 | writel(hash3, &rxmac->multi_hash3); | ||
744 | writel(hash4, &rxmac->multi_hash4); | ||
745 | } | ||
746 | |||
747 | DBG_LEAVE(et131x_dbginfo); | ||
748 | } | ||
749 | |||
750 | void SetupDeviceForUnicast(struct et131x_adapter *pAdapter) | ||
751 | { | ||
752 | struct _RXMAC_t __iomem *rxmac = &pAdapter->CSRAddress->rxmac; | ||
753 | RXMAC_UNI_PF_ADDR1_t uni_pf1; | ||
754 | RXMAC_UNI_PF_ADDR2_t uni_pf2; | ||
755 | RXMAC_UNI_PF_ADDR3_t uni_pf3; | ||
756 | PM_CSR_t pm_csr; | ||
757 | |||
758 | DBG_ENTER(et131x_dbginfo); | ||
759 | |||
760 | /* Set up unicast packet filter reg 3 to be the first two octets of | ||
761 | * the MAC address for both address | ||
762 | * | ||
763 | * Set up unicast packet filter reg 2 to be the octets 2 - 5 of the | ||
764 | * MAC address for second address | ||
765 | * | ||
766 | * Set up unicast packet filter reg 3 to be the octets 2 - 5 of the | ||
767 | * MAC address for first address | ||
768 | */ | ||
769 | uni_pf3.bits.addr1_1 = pAdapter->CurrentAddress[0]; | ||
770 | uni_pf3.bits.addr1_2 = pAdapter->CurrentAddress[1]; | ||
771 | uni_pf3.bits.addr2_1 = pAdapter->CurrentAddress[0]; | ||
772 | uni_pf3.bits.addr2_2 = pAdapter->CurrentAddress[1]; | ||
773 | |||
774 | uni_pf2.bits.addr2_3 = pAdapter->CurrentAddress[2]; | ||
775 | uni_pf2.bits.addr2_4 = pAdapter->CurrentAddress[3]; | ||
776 | uni_pf2.bits.addr2_5 = pAdapter->CurrentAddress[4]; | ||
777 | uni_pf2.bits.addr2_6 = pAdapter->CurrentAddress[5]; | ||
778 | |||
779 | uni_pf1.bits.addr1_3 = pAdapter->CurrentAddress[2]; | ||
780 | uni_pf1.bits.addr1_4 = pAdapter->CurrentAddress[3]; | ||
781 | uni_pf1.bits.addr1_5 = pAdapter->CurrentAddress[4]; | ||
782 | uni_pf1.bits.addr1_6 = pAdapter->CurrentAddress[5]; | ||
783 | |||
784 | pm_csr.value = readl(&pAdapter->CSRAddress->global.pm_csr.value); | ||
785 | if (pm_csr.bits.pm_phy_sw_coma == 0) { | ||
786 | writel(uni_pf1.value, &rxmac->uni_pf_addr1.value); | ||
787 | writel(uni_pf2.value, &rxmac->uni_pf_addr2.value); | ||
788 | writel(uni_pf3.value, &rxmac->uni_pf_addr3.value); | ||
789 | } | ||
790 | |||
791 | DBG_LEAVE(et131x_dbginfo); | ||
792 | } | ||
diff --git a/drivers/staging/et131x/et1310_mac.h b/drivers/staging/et131x/et1310_mac.h new file mode 100644 index 000000000000..bd26cd351780 --- /dev/null +++ b/drivers/staging/et131x/et1310_mac.h | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_mac.h - Defines, structs, enums, prototypes, etc. pertaining to the | ||
12 | * MAC. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef _ET1310_MAC_H_ | ||
60 | #define _ET1310_MAC_H_ | ||
61 | |||
62 | |||
63 | #include "et1310_address_map.h" | ||
64 | |||
65 | |||
66 | #define COUNTER_WRAP_28_BIT 0x10000000 | ||
67 | #define COUNTER_WRAP_22_BIT 0x400000 | ||
68 | #define COUNTER_WRAP_16_BIT 0x10000 | ||
69 | #define COUNTER_WRAP_12_BIT 0x1000 | ||
70 | |||
71 | #define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1) | ||
72 | #define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1) | ||
73 | #define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1) | ||
74 | #define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1) | ||
75 | |||
76 | #define UPDATE_COUNTER(HostCnt,DevCnt) \ | ||
77 | HostCnt = HostCnt + DevCnt; | ||
78 | |||
79 | /* Forward declaration of the private adapter structure */ | ||
80 | struct et131x_adapter; | ||
81 | |||
82 | void ConfigMACRegs1(struct et131x_adapter *adapter); | ||
83 | void ConfigMACRegs2(struct et131x_adapter *adapter); | ||
84 | void ConfigRxMacRegs(struct et131x_adapter *adapter); | ||
85 | void ConfigTxMacRegs(struct et131x_adapter *adapter); | ||
86 | void ConfigMacStatRegs(struct et131x_adapter *adapter); | ||
87 | void ConfigFlowControl(struct et131x_adapter *adapter); | ||
88 | void UpdateMacStatHostCounters(struct et131x_adapter *adapter); | ||
89 | void HandleMacStatInterrupt(struct et131x_adapter *adapter); | ||
90 | void SetupDeviceForMulticast(struct et131x_adapter *adapter); | ||
91 | void SetupDeviceForUnicast(struct et131x_adapter *adapter); | ||
92 | |||
93 | #endif /* _ET1310_MAC_H_ */ | ||
diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c new file mode 100644 index 000000000000..6c4fa54419ea --- /dev/null +++ b/drivers/staging/et131x/et1310_phy.c | |||
@@ -0,0 +1,1281 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_phy.c - Routines for configuring and accessing the PHY | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include "et131x_version.h" | ||
59 | #include "et131x_debug.h" | ||
60 | #include "et131x_defs.h" | ||
61 | |||
62 | #include <linux/pci.h> | ||
63 | #include <linux/init.h> | ||
64 | #include <linux/module.h> | ||
65 | #include <linux/types.h> | ||
66 | #include <linux/kernel.h> | ||
67 | |||
68 | #include <linux/sched.h> | ||
69 | #include <linux/ptrace.h> | ||
70 | #include <linux/slab.h> | ||
71 | #include <linux/ctype.h> | ||
72 | #include <linux/string.h> | ||
73 | #include <linux/timer.h> | ||
74 | #include <linux/interrupt.h> | ||
75 | #include <linux/in.h> | ||
76 | #include <linux/delay.h> | ||
77 | #include <asm/io.h> | ||
78 | #include <asm/system.h> | ||
79 | #include <asm/bitops.h> | ||
80 | |||
81 | #include <linux/netdevice.h> | ||
82 | #include <linux/etherdevice.h> | ||
83 | #include <linux/skbuff.h> | ||
84 | #include <linux/if_arp.h> | ||
85 | #include <linux/ioport.h> | ||
86 | #include <linux/random.h> | ||
87 | #include <linux/delay.h> | ||
88 | |||
89 | #include "et1310_phy.h" | ||
90 | #include "et1310_pm.h" | ||
91 | #include "et1310_jagcore.h" | ||
92 | |||
93 | #include "et131x_adapter.h" | ||
94 | #include "et131x_netdev.h" | ||
95 | #include "et131x_initpci.h" | ||
96 | |||
97 | #include "et1310_address_map.h" | ||
98 | #include "et1310_jagcore.h" | ||
99 | #include "et1310_tx.h" | ||
100 | #include "et1310_rx.h" | ||
101 | #include "et1310_mac.h" | ||
102 | |||
103 | /* Data for debugging facilities */ | ||
104 | #ifdef CONFIG_ET131X_DEBUG | ||
105 | extern dbg_info_t *et131x_dbginfo; | ||
106 | #endif /* CONFIG_ET131X_DEBUG */ | ||
107 | |||
108 | /* Prototypes for functions with local scope */ | ||
109 | static int et131x_xcvr_init(struct et131x_adapter *adapter); | ||
110 | |||
111 | /** | ||
112 | * PhyMiRead - Read from the PHY through the MII Interface on the MAC | ||
113 | * @adapter: pointer to our private adapter structure | ||
114 | * @xcvrAddr: the address of the transciever | ||
115 | * @xcvrReg: the register to read | ||
116 | * @value: pointer to a 16-bit value in which the value will be stored | ||
117 | * | ||
118 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
119 | */ | ||
120 | int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr, | ||
121 | uint8_t xcvrReg, uint16_t *value) | ||
122 | { | ||
123 | struct _MAC_t __iomem *mac = &adapter->CSRAddress->mac; | ||
124 | int status = 0; | ||
125 | uint32_t delay; | ||
126 | MII_MGMT_ADDR_t miiAddr; | ||
127 | MII_MGMT_CMD_t miiCmd; | ||
128 | MII_MGMT_INDICATOR_t miiIndicator; | ||
129 | |||
130 | /* Save a local copy of the registers we are dealing with so we can | ||
131 | * set them back | ||
132 | */ | ||
133 | miiAddr.value = readl(&mac->mii_mgmt_addr.value); | ||
134 | miiCmd.value = readl(&mac->mii_mgmt_cmd.value); | ||
135 | |||
136 | /* Stop the current operation */ | ||
137 | writel(0, &mac->mii_mgmt_cmd.value); | ||
138 | |||
139 | /* Set up the register we need to read from on the correct PHY */ | ||
140 | { | ||
141 | MII_MGMT_ADDR_t mii_mgmt_addr = { 0 }; | ||
142 | |||
143 | mii_mgmt_addr.bits.phy_addr = xcvrAddr; | ||
144 | mii_mgmt_addr.bits.reg_addr = xcvrReg; | ||
145 | writel(mii_mgmt_addr.value, &mac->mii_mgmt_addr.value); | ||
146 | } | ||
147 | |||
148 | /* Kick the read cycle off */ | ||
149 | delay = 0; | ||
150 | |||
151 | writel(0x1, &mac->mii_mgmt_cmd.value); | ||
152 | |||
153 | do { | ||
154 | udelay(50); | ||
155 | delay++; | ||
156 | miiIndicator.value = readl(&mac->mii_mgmt_indicator.value); | ||
157 | } while ((miiIndicator.bits.not_valid || miiIndicator.bits.busy) && | ||
158 | delay < 50); | ||
159 | |||
160 | /* If we hit the max delay, we could not read the register */ | ||
161 | if (delay >= 50) { | ||
162 | DBG_WARNING(et131x_dbginfo, | ||
163 | "xcvrReg 0x%08x could not be read\n", xcvrReg); | ||
164 | DBG_WARNING(et131x_dbginfo, "status is 0x%08x\n", | ||
165 | miiIndicator.value); | ||
166 | |||
167 | status = -EIO; | ||
168 | } | ||
169 | |||
170 | /* If we hit here we were able to read the register and we need to | ||
171 | * return the value to the caller | ||
172 | */ | ||
173 | /* TODO: make this stuff a simple readw()?! */ | ||
174 | { | ||
175 | MII_MGMT_STAT_t mii_mgmt_stat; | ||
176 | |||
177 | mii_mgmt_stat.value = readl(&mac->mii_mgmt_stat.value); | ||
178 | *value = (uint16_t) mii_mgmt_stat.bits.phy_stat; | ||
179 | } | ||
180 | |||
181 | /* Stop the read operation */ | ||
182 | writel(0, &mac->mii_mgmt_cmd.value); | ||
183 | |||
184 | DBG_VERBOSE(et131x_dbginfo, " xcvr_addr = 0x%02x, " | ||
185 | "xcvr_reg = 0x%02x, " | ||
186 | "value = 0x%04x.\n", xcvrAddr, xcvrReg, *value); | ||
187 | |||
188 | /* set the registers we touched back to the state at which we entered | ||
189 | * this function | ||
190 | */ | ||
191 | writel(miiAddr.value, &mac->mii_mgmt_addr.value); | ||
192 | writel(miiCmd.value, &mac->mii_mgmt_cmd.value); | ||
193 | |||
194 | return status; | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * MiWrite - Write to a PHY register through the MII interface of the MAC | ||
199 | * @adapter: pointer to our private adapter structure | ||
200 | * @xcvrReg: the register to read | ||
201 | * @value: 16-bit value to write | ||
202 | * | ||
203 | * Return 0 on success, errno on failure (as defined in errno.h) | ||
204 | */ | ||
205 | int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value) | ||
206 | { | ||
207 | struct _MAC_t __iomem *mac = &adapter->CSRAddress->mac; | ||
208 | int status = 0; | ||
209 | uint8_t xcvrAddr = adapter->Stats.xcvr_addr; | ||
210 | uint32_t delay; | ||
211 | MII_MGMT_ADDR_t miiAddr; | ||
212 | MII_MGMT_CMD_t miiCmd; | ||
213 | MII_MGMT_INDICATOR_t miiIndicator; | ||
214 | |||
215 | /* Save a local copy of the registers we are dealing with so we can | ||
216 | * set them back | ||
217 | */ | ||
218 | miiAddr.value = readl(&mac->mii_mgmt_addr.value); | ||
219 | miiCmd.value = readl(&mac->mii_mgmt_cmd.value); | ||
220 | |||
221 | /* Stop the current operation */ | ||
222 | writel(0, &mac->mii_mgmt_cmd.value); | ||
223 | |||
224 | /* Set up the register we need to write to on the correct PHY */ | ||
225 | { | ||
226 | MII_MGMT_ADDR_t mii_mgmt_addr; | ||
227 | |||
228 | mii_mgmt_addr.bits.phy_addr = xcvrAddr; | ||
229 | mii_mgmt_addr.bits.reg_addr = xcvrReg; | ||
230 | writel(mii_mgmt_addr.value, &mac->mii_mgmt_addr.value); | ||
231 | } | ||
232 | |||
233 | /* Add the value to write to the registers to the mac */ | ||
234 | writel(value, &mac->mii_mgmt_ctrl.value); | ||
235 | delay = 0; | ||
236 | |||
237 | do { | ||
238 | udelay(50); | ||
239 | delay++; | ||
240 | miiIndicator.value = readl(&mac->mii_mgmt_indicator.value); | ||
241 | } while (miiIndicator.bits.busy && delay < 100); | ||
242 | |||
243 | /* If we hit the max delay, we could not write the register */ | ||
244 | if (delay == 100) { | ||
245 | uint16_t TempValue; | ||
246 | |||
247 | DBG_WARNING(et131x_dbginfo, | ||
248 | "xcvrReg 0x%08x could not be written", xcvrReg); | ||
249 | DBG_WARNING(et131x_dbginfo, "status is 0x%08x\n", | ||
250 | miiIndicator.value); | ||
251 | DBG_WARNING(et131x_dbginfo, "command is 0x%08x\n", | ||
252 | readl(&mac->mii_mgmt_cmd.value)); | ||
253 | |||
254 | MiRead(adapter, xcvrReg, &TempValue); | ||
255 | |||
256 | status = -EIO; | ||
257 | } | ||
258 | |||
259 | /* Stop the write operation */ | ||
260 | writel(0, &mac->mii_mgmt_cmd.value); | ||
261 | |||
262 | /* set the registers we touched back to the state at which we entered | ||
263 | * this function | ||
264 | */ | ||
265 | writel(miiAddr.value, &mac->mii_mgmt_addr.value); | ||
266 | writel(miiCmd.value, &mac->mii_mgmt_cmd.value); | ||
267 | |||
268 | DBG_VERBOSE(et131x_dbginfo, " xcvr_addr = 0x%02x, " | ||
269 | "xcvr_reg = 0x%02x, " | ||
270 | "value = 0x%04x.\n", xcvrAddr, xcvrReg, value); | ||
271 | |||
272 | return status; | ||
273 | } | ||
274 | |||
275 | /** | ||
276 | * et131x_xcvr_find - Find the PHY ID | ||
277 | * @adapter: pointer to our private adapter structure | ||
278 | * | ||
279 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
280 | */ | ||
281 | int et131x_xcvr_find(struct et131x_adapter *adapter) | ||
282 | { | ||
283 | int status = -ENODEV; | ||
284 | uint8_t xcvr_addr; | ||
285 | MI_IDR1_t idr1; | ||
286 | MI_IDR2_t idr2; | ||
287 | uint32_t xcvr_id; | ||
288 | |||
289 | DBG_ENTER(et131x_dbginfo); | ||
290 | |||
291 | /* We need to get xcvr id and address we just get the first one */ | ||
292 | for (xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++) { | ||
293 | /* Read the ID from the PHY */ | ||
294 | PhyMiRead(adapter, xcvr_addr, | ||
295 | (uint8_t) offsetof(MI_REGS_t, idr1), | ||
296 | &idr1.value); | ||
297 | PhyMiRead(adapter, xcvr_addr, | ||
298 | (uint8_t) offsetof(MI_REGS_t, idr2), | ||
299 | &idr2.value); | ||
300 | |||
301 | xcvr_id = (uint32_t) ((idr1.value << 16) | idr2.value); | ||
302 | |||
303 | if ((idr1.value != 0) && (idr1.value != 0xffff)) { | ||
304 | DBG_TRACE(et131x_dbginfo, | ||
305 | "Xcvr addr: 0x%02x\tXcvr_id: 0x%08x\n", | ||
306 | xcvr_addr, xcvr_id); | ||
307 | |||
308 | adapter->Stats.xcvr_id = xcvr_id; | ||
309 | adapter->Stats.xcvr_addr = xcvr_addr; | ||
310 | |||
311 | status = 0; | ||
312 | break; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | DBG_LEAVE(et131x_dbginfo); | ||
317 | return status; | ||
318 | } | ||
319 | |||
320 | /** | ||
321 | * et131x_setphy_normal - Set PHY for normal operation. | ||
322 | * @adapter: pointer to our private adapter structure | ||
323 | * | ||
324 | * Used by Power Management to force the PHY into 10 Base T half-duplex mode, | ||
325 | * when going to D3 in WOL mode. Also used during initialization to set the | ||
326 | * PHY for normal operation. | ||
327 | */ | ||
328 | int et131x_setphy_normal(struct et131x_adapter *adapter) | ||
329 | { | ||
330 | int status; | ||
331 | |||
332 | DBG_ENTER(et131x_dbginfo); | ||
333 | |||
334 | /* Make sure the PHY is powered up */ | ||
335 | ET1310_PhyPowerDown(adapter, 0); | ||
336 | status = et131x_xcvr_init(adapter); | ||
337 | |||
338 | DBG_LEAVE(et131x_dbginfo); | ||
339 | return status; | ||
340 | } | ||
341 | |||
342 | /** | ||
343 | * et131x_xcvr_init - Init the phy if we are setting it into force mode | ||
344 | * @adapter: pointer to our private adapter structure | ||
345 | * | ||
346 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
347 | */ | ||
348 | static int et131x_xcvr_init(struct et131x_adapter *adapter) | ||
349 | { | ||
350 | int status = 0; | ||
351 | MI_IMR_t imr; | ||
352 | MI_ISR_t isr; | ||
353 | MI_LCR2_t lcr2; | ||
354 | |||
355 | DBG_ENTER(et131x_dbginfo); | ||
356 | |||
357 | /* Zero out the adapter structure variable representing BMSR */ | ||
358 | adapter->Bmsr.value = 0; | ||
359 | |||
360 | MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, isr), &isr.value); | ||
361 | |||
362 | MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, imr), &imr.value); | ||
363 | |||
364 | /* Set the link status interrupt only. Bad behavior when link status | ||
365 | * and auto neg are set, we run into a nested interrupt problem | ||
366 | */ | ||
367 | imr.bits.int_en = 0x1; | ||
368 | imr.bits.link_status = 0x1; | ||
369 | imr.bits.autoneg_status = 0x1; | ||
370 | |||
371 | MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, imr), imr.value); | ||
372 | |||
373 | /* Set the LED behavior such that LED 1 indicates speed (off = | ||
374 | * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates | ||
375 | * link and activity (on for link, blink off for activity). | ||
376 | * | ||
377 | * NOTE: Some customizations have been added here for specific | ||
378 | * vendors; The LED behavior is now determined by vendor data in the | ||
379 | * EEPROM. However, the above description is the default. | ||
380 | */ | ||
381 | if ((adapter->eepromData[1] & 0x4) == 0) { | ||
382 | MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, lcr2), | ||
383 | &lcr2.value); | ||
384 | if ((adapter->eepromData[1] & 0x8) == 0) | ||
385 | lcr2.bits.led_tx_rx = 0x3; | ||
386 | else | ||
387 | lcr2.bits.led_tx_rx = 0x4; | ||
388 | lcr2.bits.led_link = 0xa; | ||
389 | MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, lcr2), | ||
390 | lcr2.value); | ||
391 | } | ||
392 | |||
393 | /* Determine if we need to go into a force mode and set it */ | ||
394 | if (adapter->AiForceSpeed == 0 && adapter->AiForceDpx == 0) { | ||
395 | if ((adapter->RegistryFlowControl == TxOnly) || | ||
396 | (adapter->RegistryFlowControl == Both)) { | ||
397 | ET1310_PhyAccessMiBit(adapter, | ||
398 | TRUEPHY_BIT_SET, 4, 11, NULL); | ||
399 | } else { | ||
400 | ET1310_PhyAccessMiBit(adapter, | ||
401 | TRUEPHY_BIT_CLEAR, 4, 11, NULL); | ||
402 | } | ||
403 | |||
404 | if (adapter->RegistryFlowControl == Both) { | ||
405 | ET1310_PhyAccessMiBit(adapter, | ||
406 | TRUEPHY_BIT_SET, 4, 10, NULL); | ||
407 | } else { | ||
408 | ET1310_PhyAccessMiBit(adapter, | ||
409 | TRUEPHY_BIT_CLEAR, 4, 10, NULL); | ||
410 | } | ||
411 | |||
412 | /* Set the phy to autonegotiation */ | ||
413 | ET1310_PhyAutoNeg(adapter, true); | ||
414 | |||
415 | /* NOTE - Do we need this? */ | ||
416 | ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL); | ||
417 | |||
418 | DBG_LEAVE(et131x_dbginfo); | ||
419 | return status; | ||
420 | } else { | ||
421 | ET1310_PhyAutoNeg(adapter, false); | ||
422 | |||
423 | /* Set to the correct force mode. */ | ||
424 | if (adapter->AiForceDpx != 1) { | ||
425 | if ((adapter->RegistryFlowControl == TxOnly) || | ||
426 | (adapter->RegistryFlowControl == Both)) { | ||
427 | ET1310_PhyAccessMiBit(adapter, | ||
428 | TRUEPHY_BIT_SET, 4, 11, | ||
429 | NULL); | ||
430 | } else { | ||
431 | ET1310_PhyAccessMiBit(adapter, | ||
432 | TRUEPHY_BIT_CLEAR, 4, 11, | ||
433 | NULL); | ||
434 | } | ||
435 | |||
436 | if (adapter->RegistryFlowControl == Both) { | ||
437 | ET1310_PhyAccessMiBit(adapter, | ||
438 | TRUEPHY_BIT_SET, 4, 10, | ||
439 | NULL); | ||
440 | } else { | ||
441 | ET1310_PhyAccessMiBit(adapter, | ||
442 | TRUEPHY_BIT_CLEAR, 4, 10, | ||
443 | NULL); | ||
444 | } | ||
445 | } else { | ||
446 | ET1310_PhyAccessMiBit(adapter, | ||
447 | TRUEPHY_BIT_CLEAR, 4, 10, NULL); | ||
448 | ET1310_PhyAccessMiBit(adapter, | ||
449 | TRUEPHY_BIT_CLEAR, 4, 11, NULL); | ||
450 | } | ||
451 | |||
452 | switch (adapter->AiForceSpeed) { | ||
453 | case 10: | ||
454 | if (adapter->AiForceDpx == 1) { | ||
455 | TPAL_SetPhy10HalfDuplex(adapter); | ||
456 | } else if (adapter->AiForceDpx == 2) { | ||
457 | TPAL_SetPhy10FullDuplex(adapter); | ||
458 | } else { | ||
459 | TPAL_SetPhy10Force(adapter); | ||
460 | } | ||
461 | break; | ||
462 | case 100: | ||
463 | if (adapter->AiForceDpx == 1) { | ||
464 | TPAL_SetPhy100HalfDuplex(adapter); | ||
465 | } else if (adapter->AiForceDpx == 2) { | ||
466 | TPAL_SetPhy100FullDuplex(adapter); | ||
467 | } else { | ||
468 | TPAL_SetPhy100Force(adapter); | ||
469 | } | ||
470 | break; | ||
471 | case 1000: | ||
472 | TPAL_SetPhy1000FullDuplex(adapter); | ||
473 | break; | ||
474 | } | ||
475 | |||
476 | DBG_LEAVE(et131x_dbginfo); | ||
477 | return status; | ||
478 | } | ||
479 | } | ||
480 | |||
481 | void et131x_Mii_check(struct et131x_adapter *pAdapter, | ||
482 | MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints) | ||
483 | { | ||
484 | uint8_t ucLinkStatus; | ||
485 | uint32_t uiAutoNegStatus; | ||
486 | uint32_t uiSpeed; | ||
487 | uint32_t uiDuplex; | ||
488 | uint32_t uiMdiMdix; | ||
489 | uint32_t uiMasterSlave; | ||
490 | uint32_t uiPolarity; | ||
491 | unsigned long lockflags; | ||
492 | |||
493 | DBG_ENTER(et131x_dbginfo); | ||
494 | |||
495 | if (bmsr_ints.bits.link_status) { | ||
496 | if (bmsr.bits.link_status) { | ||
497 | pAdapter->PoMgmt.TransPhyComaModeOnBoot = 20; | ||
498 | |||
499 | /* Update our state variables and indicate the | ||
500 | * connected state | ||
501 | */ | ||
502 | spin_lock_irqsave(&pAdapter->Lock, lockflags); | ||
503 | |||
504 | pAdapter->MediaState = NETIF_STATUS_MEDIA_CONNECT; | ||
505 | MP_CLEAR_FLAG(pAdapter, fMP_ADAPTER_LINK_DETECTION); | ||
506 | |||
507 | spin_unlock_irqrestore(&pAdapter->Lock, lockflags); | ||
508 | |||
509 | /* Don't indicate state if we're in loopback mode */ | ||
510 | if (pAdapter->RegistryPhyLoopbk == false) { | ||
511 | netif_carrier_on(pAdapter->netdev); | ||
512 | } | ||
513 | } else { | ||
514 | DBG_WARNING(et131x_dbginfo, | ||
515 | "Link down cable problem\n"); | ||
516 | |||
517 | if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS) { | ||
518 | // NOTE - Is there a way to query this without TruePHY? | ||
519 | // && TRU_QueryCoreType(pAdapter->hTruePhy, 0) == EMI_TRUEPHY_A13O) { | ||
520 | uint16_t Register18; | ||
521 | |||
522 | MiRead(pAdapter, 0x12, &Register18); | ||
523 | MiWrite(pAdapter, 0x12, Register18 | 0x4); | ||
524 | MiWrite(pAdapter, 0x10, Register18 | 0x8402); | ||
525 | MiWrite(pAdapter, 0x11, Register18 | 511); | ||
526 | MiWrite(pAdapter, 0x12, Register18); | ||
527 | } | ||
528 | |||
529 | /* For the first N seconds of life, we are in "link | ||
530 | * detection" When we are in this state, we should | ||
531 | * only report "connected". When the LinkDetection | ||
532 | * Timer expires, we can report disconnected (handled | ||
533 | * in the LinkDetectionDPC). | ||
534 | */ | ||
535 | if ((MP_IS_FLAG_CLEAR | ||
536 | (pAdapter, fMP_ADAPTER_LINK_DETECTION)) | ||
537 | || (pAdapter->MediaState == | ||
538 | NETIF_STATUS_MEDIA_DISCONNECT)) { | ||
539 | spin_lock_irqsave(&pAdapter->Lock, lockflags); | ||
540 | pAdapter->MediaState = | ||
541 | NETIF_STATUS_MEDIA_DISCONNECT; | ||
542 | spin_unlock_irqrestore(&pAdapter->Lock, | ||
543 | lockflags); | ||
544 | |||
545 | /* Only indicate state if we're in loopback | ||
546 | * mode | ||
547 | */ | ||
548 | if (pAdapter->RegistryPhyLoopbk == false) { | ||
549 | netif_carrier_off(pAdapter->netdev); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | pAdapter->uiLinkSpeed = 0; | ||
554 | pAdapter->uiDuplexMode = 0; | ||
555 | |||
556 | /* Free the packets being actively sent & stopped */ | ||
557 | et131x_free_busy_send_packets(pAdapter); | ||
558 | |||
559 | /* Re-initialize the send structures */ | ||
560 | et131x_init_send(pAdapter); | ||
561 | |||
562 | /* Reset the RFD list and re-start RU */ | ||
563 | et131x_reset_recv(pAdapter); | ||
564 | |||
565 | /* | ||
566 | * Bring the device back to the state it was during | ||
567 | * init prior to autonegotiation being complete. This | ||
568 | * way, when we get the auto-neg complete interrupt, | ||
569 | * we can complete init by calling ConfigMacREGS2. | ||
570 | */ | ||
571 | et131x_soft_reset(pAdapter); | ||
572 | |||
573 | /* Setup ET1310 as per the documentation */ | ||
574 | et131x_adapter_setup(pAdapter); | ||
575 | |||
576 | /* Setup the PHY into coma mode until the cable is | ||
577 | * plugged back in | ||
578 | */ | ||
579 | if (pAdapter->RegistryPhyComa == 1) { | ||
580 | EnablePhyComa(pAdapter); | ||
581 | } | ||
582 | } | ||
583 | } | ||
584 | |||
585 | if (bmsr_ints.bits.auto_neg_complete || | ||
586 | ((pAdapter->AiForceDpx == 3) && (bmsr_ints.bits.link_status))) { | ||
587 | if (bmsr.bits.auto_neg_complete || (pAdapter->AiForceDpx == 3)) { | ||
588 | ET1310_PhyLinkStatus(pAdapter, | ||
589 | &ucLinkStatus, &uiAutoNegStatus, | ||
590 | &uiSpeed, &uiDuplex, &uiMdiMdix, | ||
591 | &uiMasterSlave, &uiPolarity); | ||
592 | |||
593 | pAdapter->uiLinkSpeed = uiSpeed; | ||
594 | pAdapter->uiDuplexMode = uiDuplex; | ||
595 | |||
596 | DBG_TRACE(et131x_dbginfo, | ||
597 | "pAdapter->uiLinkSpeed 0x%04x, pAdapter->uiDuplex 0x%08x\n", | ||
598 | pAdapter->uiLinkSpeed, | ||
599 | pAdapter->uiDuplexMode); | ||
600 | |||
601 | pAdapter->PoMgmt.TransPhyComaModeOnBoot = 20; | ||
602 | |||
603 | if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS) { | ||
604 | // NOTE - Is there a way to query this without TruePHY? | ||
605 | // && TRU_QueryCoreType(pAdapter->hTruePhy, 0) == EMI_TRUEPHY_A13O) { | ||
606 | uint16_t Register18; | ||
607 | |||
608 | MiRead(pAdapter, 0x12, &Register18); | ||
609 | MiWrite(pAdapter, 0x12, Register18 | 0x4); | ||
610 | MiWrite(pAdapter, 0x10, Register18 | 0x8402); | ||
611 | MiWrite(pAdapter, 0x11, Register18 | 511); | ||
612 | MiWrite(pAdapter, 0x12, Register18); | ||
613 | } | ||
614 | |||
615 | ConfigFlowControl(pAdapter); | ||
616 | |||
617 | if ((pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) && | ||
618 | (pAdapter->RegistryJumboPacket > 2048)) | ||
619 | { | ||
620 | ET1310_PhyAndOrReg(pAdapter, 0x16, 0xcfff, | ||
621 | 0x2000); | ||
622 | } | ||
623 | |||
624 | SetRxDmaTimer(pAdapter); | ||
625 | ConfigMACRegs2(pAdapter); | ||
626 | } | ||
627 | } | ||
628 | |||
629 | DBG_LEAVE(et131x_dbginfo); | ||
630 | } | ||
631 | |||
632 | /** | ||
633 | * TPAL_SetPhy10HalfDuplex - Force the phy into 10 Base T Half Duplex mode. | ||
634 | * @pAdapter: pointer to the adapter structure | ||
635 | * | ||
636 | * Also sets the MAC so it is syncd up properly | ||
637 | */ | ||
638 | void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *pAdapter) | ||
639 | { | ||
640 | DBG_ENTER(et131x_dbginfo); | ||
641 | |||
642 | /* Power down PHY */ | ||
643 | ET1310_PhyPowerDown(pAdapter, 1); | ||
644 | |||
645 | /* First we need to turn off all other advertisement */ | ||
646 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
647 | |||
648 | ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
649 | |||
650 | /* Set our advertise values accordingly */ | ||
651 | ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_HALF); | ||
652 | |||
653 | /* Power up PHY */ | ||
654 | ET1310_PhyPowerDown(pAdapter, 0); | ||
655 | |||
656 | DBG_LEAVE(et131x_dbginfo); | ||
657 | } | ||
658 | |||
659 | /** | ||
660 | * TPAL_SetPhy10FullDuplex - Force the phy into 10 Base T Full Duplex mode. | ||
661 | * @pAdapter: pointer to the adapter structure | ||
662 | * | ||
663 | * Also sets the MAC so it is syncd up properly | ||
664 | */ | ||
665 | void TPAL_SetPhy10FullDuplex(struct et131x_adapter *pAdapter) | ||
666 | { | ||
667 | DBG_ENTER(et131x_dbginfo); | ||
668 | |||
669 | /* Power down PHY */ | ||
670 | ET1310_PhyPowerDown(pAdapter, 1); | ||
671 | |||
672 | /* First we need to turn off all other advertisement */ | ||
673 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
674 | |||
675 | ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
676 | |||
677 | /* Set our advertise values accordingly */ | ||
678 | ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL); | ||
679 | |||
680 | /* Power up PHY */ | ||
681 | ET1310_PhyPowerDown(pAdapter, 0); | ||
682 | |||
683 | DBG_LEAVE(et131x_dbginfo); | ||
684 | } | ||
685 | |||
686 | /** | ||
687 | * TPAL_SetPhy10Force - Force Base-T FD mode WITHOUT using autonegotiation | ||
688 | * @pAdapter: pointer to the adapter structure | ||
689 | */ | ||
690 | void TPAL_SetPhy10Force(struct et131x_adapter *pAdapter) | ||
691 | { | ||
692 | DBG_ENTER(et131x_dbginfo); | ||
693 | |||
694 | /* Power down PHY */ | ||
695 | ET1310_PhyPowerDown(pAdapter, 1); | ||
696 | |||
697 | /* Disable autoneg */ | ||
698 | ET1310_PhyAutoNeg(pAdapter, false); | ||
699 | |||
700 | /* Disable all advertisement */ | ||
701 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
702 | ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
703 | ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
704 | |||
705 | /* Force 10 Mbps */ | ||
706 | ET1310_PhySpeedSelect(pAdapter, TRUEPHY_SPEED_10MBPS); | ||
707 | |||
708 | /* Force Full duplex */ | ||
709 | ET1310_PhyDuplexMode(pAdapter, TRUEPHY_DUPLEX_FULL); | ||
710 | |||
711 | /* Power up PHY */ | ||
712 | ET1310_PhyPowerDown(pAdapter, 0); | ||
713 | |||
714 | DBG_LEAVE(et131x_dbginfo); | ||
715 | } | ||
716 | |||
717 | /** | ||
718 | * TPAL_SetPhy100HalfDuplex - Force 100 Base T Half Duplex mode. | ||
719 | * @pAdapter: pointer to the adapter structure | ||
720 | * | ||
721 | * Also sets the MAC so it is syncd up properly. | ||
722 | */ | ||
723 | void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *pAdapter) | ||
724 | { | ||
725 | DBG_ENTER(et131x_dbginfo); | ||
726 | |||
727 | /* Power down PHY */ | ||
728 | ET1310_PhyPowerDown(pAdapter, 1); | ||
729 | |||
730 | /* first we need to turn off all other advertisement */ | ||
731 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
732 | |||
733 | ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
734 | |||
735 | /* Set our advertise values accordingly */ | ||
736 | ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_HALF); | ||
737 | |||
738 | /* Set speed */ | ||
739 | ET1310_PhySpeedSelect(pAdapter, TRUEPHY_SPEED_100MBPS); | ||
740 | |||
741 | /* Power up PHY */ | ||
742 | ET1310_PhyPowerDown(pAdapter, 0); | ||
743 | |||
744 | DBG_LEAVE(et131x_dbginfo); | ||
745 | } | ||
746 | |||
747 | /** | ||
748 | * TPAL_SetPhy100FullDuplex - Force 100 Base T Full Duplex mode. | ||
749 | * @pAdapter: pointer to the adapter structure | ||
750 | * | ||
751 | * Also sets the MAC so it is syncd up properly | ||
752 | */ | ||
753 | void TPAL_SetPhy100FullDuplex(struct et131x_adapter *pAdapter) | ||
754 | { | ||
755 | DBG_ENTER(et131x_dbginfo); | ||
756 | |||
757 | /* Power down PHY */ | ||
758 | ET1310_PhyPowerDown(pAdapter, 1); | ||
759 | |||
760 | /* First we need to turn off all other advertisement */ | ||
761 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
762 | |||
763 | ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
764 | |||
765 | /* Set our advertise values accordingly */ | ||
766 | ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL); | ||
767 | |||
768 | /* Power up PHY */ | ||
769 | ET1310_PhyPowerDown(pAdapter, 0); | ||
770 | |||
771 | DBG_LEAVE(et131x_dbginfo); | ||
772 | } | ||
773 | |||
774 | /** | ||
775 | * TPAL_SetPhy100Force - Force 100 BaseT FD mode WITHOUT using autonegotiation | ||
776 | * @pAdapter: pointer to the adapter structure | ||
777 | */ | ||
778 | void TPAL_SetPhy100Force(struct et131x_adapter *pAdapter) | ||
779 | { | ||
780 | DBG_ENTER(et131x_dbginfo); | ||
781 | |||
782 | /* Power down PHY */ | ||
783 | ET1310_PhyPowerDown(pAdapter, 1); | ||
784 | |||
785 | /* Disable autoneg */ | ||
786 | ET1310_PhyAutoNeg(pAdapter, false); | ||
787 | |||
788 | /* Disable all advertisement */ | ||
789 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
790 | ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
791 | ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
792 | |||
793 | /* Force 100 Mbps */ | ||
794 | ET1310_PhySpeedSelect(pAdapter, TRUEPHY_SPEED_100MBPS); | ||
795 | |||
796 | /* Force Full duplex */ | ||
797 | ET1310_PhyDuplexMode(pAdapter, TRUEPHY_DUPLEX_FULL); | ||
798 | |||
799 | /* Power up PHY */ | ||
800 | ET1310_PhyPowerDown(pAdapter, 0); | ||
801 | |||
802 | DBG_LEAVE(et131x_dbginfo); | ||
803 | } | ||
804 | |||
805 | /** | ||
806 | * TPAL_SetPhy1000FullDuplex - Force 1000 Base T Full Duplex mode | ||
807 | * @pAdapter: pointer to the adapter structure | ||
808 | * | ||
809 | * Also sets the MAC so it is syncd up properly. | ||
810 | */ | ||
811 | void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *pAdapter) | ||
812 | { | ||
813 | DBG_ENTER(et131x_dbginfo); | ||
814 | |||
815 | /* Power down PHY */ | ||
816 | ET1310_PhyPowerDown(pAdapter, 1); | ||
817 | |||
818 | /* first we need to turn off all other advertisement */ | ||
819 | ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
820 | |||
821 | ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
822 | |||
823 | /* set our advertise values accordingly */ | ||
824 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL); | ||
825 | |||
826 | /* power up PHY */ | ||
827 | ET1310_PhyPowerDown(pAdapter, 0); | ||
828 | |||
829 | DBG_LEAVE(et131x_dbginfo); | ||
830 | } | ||
831 | |||
832 | /** | ||
833 | * TPAL_SetPhyAutoNeg - Set phy to autonegotiation mode. | ||
834 | * @pAdapter: pointer to the adapter structure | ||
835 | */ | ||
836 | void TPAL_SetPhyAutoNeg(struct et131x_adapter *pAdapter) | ||
837 | { | ||
838 | DBG_ENTER(et131x_dbginfo); | ||
839 | |||
840 | /* Power down PHY */ | ||
841 | ET1310_PhyPowerDown(pAdapter, 1); | ||
842 | |||
843 | /* Turn on advertisement of all capabilities */ | ||
844 | ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_BOTH); | ||
845 | |||
846 | ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_BOTH); | ||
847 | |||
848 | if (pAdapter->DeviceID != ET131X_PCI_DEVICE_ID_FAST) { | ||
849 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL); | ||
850 | } else { | ||
851 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
852 | } | ||
853 | |||
854 | /* Make sure auto-neg is ON (it is disabled in FORCE modes) */ | ||
855 | ET1310_PhyAutoNeg(pAdapter, true); | ||
856 | |||
857 | /* Power up PHY */ | ||
858 | ET1310_PhyPowerDown(pAdapter, 0); | ||
859 | |||
860 | DBG_LEAVE(et131x_dbginfo); | ||
861 | } | ||
862 | |||
863 | |||
864 | /* | ||
865 | * The routines which follow provide low-level access to the PHY, and are used | ||
866 | * primarily by the routines above (although there are a few places elsewhere | ||
867 | * in the driver where this level of access is required). | ||
868 | */ | ||
869 | |||
870 | static const uint16_t ConfigPhy[25][2] = { | ||
871 | /* Reg Value Register */ | ||
872 | /* Addr */ | ||
873 | {0x880B, 0x0926}, /* AfeIfCreg4B1000Msbs */ | ||
874 | {0x880C, 0x0926}, /* AfeIfCreg4B100Msbs */ | ||
875 | {0x880D, 0x0926}, /* AfeIfCreg4B10Msbs */ | ||
876 | |||
877 | {0x880E, 0xB4D3}, /* AfeIfCreg4B1000Lsbs */ | ||
878 | {0x880F, 0xB4D3}, /* AfeIfCreg4B100Lsbs */ | ||
879 | {0x8810, 0xB4D3}, /* AfeIfCreg4B10Lsbs */ | ||
880 | |||
881 | {0x8805, 0xB03E}, /* AfeIfCreg3B1000Msbs */ | ||
882 | {0x8806, 0xB03E}, /* AfeIfCreg3B100Msbs */ | ||
883 | {0x8807, 0xFF00}, /* AfeIfCreg3B10Msbs */ | ||
884 | |||
885 | {0x8808, 0xE090}, /* AfeIfCreg3B1000Lsbs */ | ||
886 | {0x8809, 0xE110}, /* AfeIfCreg3B100Lsbs */ | ||
887 | {0x880A, 0x0000}, /* AfeIfCreg3B10Lsbs */ | ||
888 | |||
889 | {0x300D, 1}, /* DisableNorm */ | ||
890 | |||
891 | {0x280C, 0x0180}, /* LinkHoldEnd */ | ||
892 | |||
893 | {0x1C21, 0x0002}, /* AlphaM */ | ||
894 | |||
895 | {0x3821, 6}, /* FfeLkgTx0 */ | ||
896 | {0x381D, 1}, /* FfeLkg1g4 */ | ||
897 | {0x381E, 1}, /* FfeLkg1g5 */ | ||
898 | {0x381F, 1}, /* FfeLkg1g6 */ | ||
899 | {0x3820, 1}, /* FfeLkg1g7 */ | ||
900 | |||
901 | {0x8402, 0x01F0}, /* Btinact */ | ||
902 | {0x800E, 20}, /* LftrainTime */ | ||
903 | {0x800F, 24}, /* DvguardTime */ | ||
904 | {0x8010, 46}, /* IdlguardTime */ | ||
905 | |||
906 | {0, 0} | ||
907 | |||
908 | }; | ||
909 | |||
910 | /* condensed version of the phy initialization routine */ | ||
911 | void ET1310_PhyInit(struct et131x_adapter *pAdapter) | ||
912 | { | ||
913 | uint16_t usData, usIndex; | ||
914 | |||
915 | if (pAdapter == NULL) { | ||
916 | return; | ||
917 | } | ||
918 | |||
919 | // get the identity (again ?) | ||
920 | MiRead(pAdapter, PHY_ID_1, &usData); | ||
921 | MiRead(pAdapter, PHY_ID_2, &usData); | ||
922 | |||
923 | // what does this do/achieve ? | ||
924 | MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData); // should read 0002 | ||
925 | MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0006); | ||
926 | |||
927 | // read modem register 0402, should I do something with the return data ? | ||
928 | MiWrite(pAdapter, PHY_INDEX_REG, 0x0402); | ||
929 | MiRead(pAdapter, PHY_DATA_REG, &usData); | ||
930 | |||
931 | // what does this do/achieve ? | ||
932 | MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0002); | ||
933 | |||
934 | // get the identity (again ?) | ||
935 | MiRead(pAdapter, PHY_ID_1, &usData); | ||
936 | MiRead(pAdapter, PHY_ID_2, &usData); | ||
937 | |||
938 | // what does this achieve ? | ||
939 | MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData); // should read 0002 | ||
940 | MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0006); | ||
941 | |||
942 | // read modem register 0402, should I do something with the return data? | ||
943 | MiWrite(pAdapter, PHY_INDEX_REG, 0x0402); | ||
944 | MiRead(pAdapter, PHY_DATA_REG, &usData); | ||
945 | |||
946 | MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0002); | ||
947 | |||
948 | // what does this achieve (should return 0x1040) | ||
949 | MiRead(pAdapter, PHY_CONTROL, &usData); | ||
950 | MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData); // should read 0002 | ||
951 | MiWrite(pAdapter, PHY_CONTROL, 0x1840); | ||
952 | |||
953 | MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0007); | ||
954 | |||
955 | // here the writing of the array starts.... | ||
956 | usIndex = 0; | ||
957 | while (ConfigPhy[usIndex][0] != 0x0000) { | ||
958 | // write value | ||
959 | MiWrite(pAdapter, PHY_INDEX_REG, ConfigPhy[usIndex][0]); | ||
960 | MiWrite(pAdapter, PHY_DATA_REG, ConfigPhy[usIndex][1]); | ||
961 | |||
962 | // read it back | ||
963 | MiWrite(pAdapter, PHY_INDEX_REG, ConfigPhy[usIndex][0]); | ||
964 | MiRead(pAdapter, PHY_DATA_REG, &usData); | ||
965 | |||
966 | // do a check on the value read back ? | ||
967 | usIndex++; | ||
968 | } | ||
969 | // here the writing of the array ends... | ||
970 | |||
971 | MiRead(pAdapter, PHY_CONTROL, &usData); // 0x1840 | ||
972 | MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData); // should read 0007 | ||
973 | MiWrite(pAdapter, PHY_CONTROL, 0x1040); | ||
974 | MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0002); | ||
975 | } | ||
976 | |||
977 | void ET1310_PhyReset(struct et131x_adapter *pAdapter) | ||
978 | { | ||
979 | MiWrite(pAdapter, PHY_CONTROL, 0x8000); | ||
980 | } | ||
981 | |||
982 | void ET1310_PhyPowerDown(struct et131x_adapter *pAdapter, bool down) | ||
983 | { | ||
984 | uint16_t usData; | ||
985 | |||
986 | MiRead(pAdapter, PHY_CONTROL, &usData); | ||
987 | |||
988 | if (down == false) { | ||
989 | // Power UP | ||
990 | usData &= ~0x0800; | ||
991 | MiWrite(pAdapter, PHY_CONTROL, usData); | ||
992 | } else { | ||
993 | // Power DOWN | ||
994 | usData |= 0x0800; | ||
995 | MiWrite(pAdapter, PHY_CONTROL, usData); | ||
996 | } | ||
997 | } | ||
998 | |||
999 | void ET1310_PhyAutoNeg(struct et131x_adapter *pAdapter, bool enable) | ||
1000 | { | ||
1001 | uint16_t usData; | ||
1002 | |||
1003 | MiRead(pAdapter, PHY_CONTROL, &usData); | ||
1004 | |||
1005 | if (enable == true) { | ||
1006 | // Autonegotiation ON | ||
1007 | usData |= 0x1000; | ||
1008 | MiWrite(pAdapter, PHY_CONTROL, usData); | ||
1009 | } else { | ||
1010 | // Autonegotiation OFF | ||
1011 | usData &= ~0x1000; | ||
1012 | MiWrite(pAdapter, PHY_CONTROL, usData); | ||
1013 | } | ||
1014 | } | ||
1015 | |||
1016 | void ET1310_PhyDuplexMode(struct et131x_adapter *pAdapter, uint16_t duplex) | ||
1017 | { | ||
1018 | uint16_t usData; | ||
1019 | |||
1020 | MiRead(pAdapter, PHY_CONTROL, &usData); | ||
1021 | |||
1022 | if (duplex == TRUEPHY_DUPLEX_FULL) { | ||
1023 | // Set Full Duplex | ||
1024 | usData |= 0x100; | ||
1025 | MiWrite(pAdapter, PHY_CONTROL, usData); | ||
1026 | } else { | ||
1027 | // Set Half Duplex | ||
1028 | usData &= ~0x100; | ||
1029 | MiWrite(pAdapter, PHY_CONTROL, usData); | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | void ET1310_PhySpeedSelect(struct et131x_adapter *pAdapter, uint16_t speed) | ||
1034 | { | ||
1035 | uint16_t usData; | ||
1036 | |||
1037 | // Read the PHY control register | ||
1038 | MiRead(pAdapter, PHY_CONTROL, &usData); | ||
1039 | |||
1040 | // Clear all Speed settings (Bits 6, 13) | ||
1041 | usData &= ~0x2040; | ||
1042 | |||
1043 | // Reset the speed bits based on user selection | ||
1044 | switch (speed) { | ||
1045 | case TRUEPHY_SPEED_10MBPS: | ||
1046 | // Bits already cleared above, do nothing | ||
1047 | break; | ||
1048 | |||
1049 | case TRUEPHY_SPEED_100MBPS: | ||
1050 | // 100M == Set bit 13 | ||
1051 | usData |= 0x2000; | ||
1052 | break; | ||
1053 | |||
1054 | case TRUEPHY_SPEED_1000MBPS: | ||
1055 | default: | ||
1056 | usData |= 0x0040; | ||
1057 | break; | ||
1058 | } | ||
1059 | |||
1060 | // Write back the new speed | ||
1061 | MiWrite(pAdapter, PHY_CONTROL, usData); | ||
1062 | } | ||
1063 | |||
1064 | void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *pAdapter, | ||
1065 | uint16_t duplex) | ||
1066 | { | ||
1067 | uint16_t usData; | ||
1068 | |||
1069 | // Read the PHY 1000 Base-T Control Register | ||
1070 | MiRead(pAdapter, PHY_1000_CONTROL, &usData); | ||
1071 | |||
1072 | // Clear Bits 8,9 | ||
1073 | usData &= ~0x0300; | ||
1074 | |||
1075 | switch (duplex) { | ||
1076 | case TRUEPHY_ADV_DUPLEX_NONE: | ||
1077 | // Duplex already cleared, do nothing | ||
1078 | break; | ||
1079 | |||
1080 | case TRUEPHY_ADV_DUPLEX_FULL: | ||
1081 | // Set Bit 9 | ||
1082 | usData |= 0x0200; | ||
1083 | break; | ||
1084 | |||
1085 | case TRUEPHY_ADV_DUPLEX_HALF: | ||
1086 | // Set Bit 8 | ||
1087 | usData |= 0x0100; | ||
1088 | break; | ||
1089 | |||
1090 | case TRUEPHY_ADV_DUPLEX_BOTH: | ||
1091 | default: | ||
1092 | usData |= 0x0300; | ||
1093 | break; | ||
1094 | } | ||
1095 | |||
1096 | // Write back advertisement | ||
1097 | MiWrite(pAdapter, PHY_1000_CONTROL, usData); | ||
1098 | } | ||
1099 | |||
1100 | void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *pAdapter, | ||
1101 | uint16_t duplex) | ||
1102 | { | ||
1103 | uint16_t usData; | ||
1104 | |||
1105 | // Read the Autonegotiation Register (10/100) | ||
1106 | MiRead(pAdapter, PHY_AUTO_ADVERTISEMENT, &usData); | ||
1107 | |||
1108 | // Clear bits 7,8 | ||
1109 | usData &= ~0x0180; | ||
1110 | |||
1111 | switch (duplex) { | ||
1112 | case TRUEPHY_ADV_DUPLEX_NONE: | ||
1113 | // Duplex already cleared, do nothing | ||
1114 | break; | ||
1115 | |||
1116 | case TRUEPHY_ADV_DUPLEX_FULL: | ||
1117 | // Set Bit 8 | ||
1118 | usData |= 0x0100; | ||
1119 | break; | ||
1120 | |||
1121 | case TRUEPHY_ADV_DUPLEX_HALF: | ||
1122 | // Set Bit 7 | ||
1123 | usData |= 0x0080; | ||
1124 | break; | ||
1125 | |||
1126 | case TRUEPHY_ADV_DUPLEX_BOTH: | ||
1127 | default: | ||
1128 | // Set Bits 7,8 | ||
1129 | usData |= 0x0180; | ||
1130 | break; | ||
1131 | } | ||
1132 | |||
1133 | // Write back advertisement | ||
1134 | MiWrite(pAdapter, PHY_AUTO_ADVERTISEMENT, usData); | ||
1135 | } | ||
1136 | |||
1137 | void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *pAdapter, | ||
1138 | uint16_t duplex) | ||
1139 | { | ||
1140 | uint16_t usData; | ||
1141 | |||
1142 | // Read the Autonegotiation Register (10/100) | ||
1143 | MiRead(pAdapter, PHY_AUTO_ADVERTISEMENT, &usData); | ||
1144 | |||
1145 | // Clear bits 5,6 | ||
1146 | usData &= ~0x0060; | ||
1147 | |||
1148 | switch (duplex) { | ||
1149 | case TRUEPHY_ADV_DUPLEX_NONE: | ||
1150 | // Duplex already cleared, do nothing | ||
1151 | break; | ||
1152 | |||
1153 | case TRUEPHY_ADV_DUPLEX_FULL: | ||
1154 | // Set Bit 6 | ||
1155 | usData |= 0x0040; | ||
1156 | break; | ||
1157 | |||
1158 | case TRUEPHY_ADV_DUPLEX_HALF: | ||
1159 | // Set Bit 5 | ||
1160 | usData |= 0x0020; | ||
1161 | break; | ||
1162 | |||
1163 | case TRUEPHY_ADV_DUPLEX_BOTH: | ||
1164 | default: | ||
1165 | // Set Bits 5,6 | ||
1166 | usData |= 0x0060; | ||
1167 | break; | ||
1168 | } | ||
1169 | |||
1170 | // Write back advertisement | ||
1171 | MiWrite(pAdapter, PHY_AUTO_ADVERTISEMENT, usData); | ||
1172 | } | ||
1173 | |||
1174 | void ET1310_PhyLinkStatus(struct et131x_adapter *pAdapter, | ||
1175 | uint8_t *ucLinkStatus, | ||
1176 | uint32_t *uiAutoNeg, | ||
1177 | uint32_t *uiLinkSpeed, | ||
1178 | uint32_t *uiDuplexMode, | ||
1179 | uint32_t *uiMdiMdix, | ||
1180 | uint32_t *uiMasterSlave, uint32_t *uiPolarity) | ||
1181 | { | ||
1182 | uint16_t usMiStatus = 0; | ||
1183 | uint16_t us1000BaseT = 0; | ||
1184 | uint16_t usVmiPhyStatus = 0; | ||
1185 | uint16_t usControl = 0; | ||
1186 | |||
1187 | MiRead(pAdapter, PHY_STATUS, &usMiStatus); | ||
1188 | MiRead(pAdapter, PHY_1000_STATUS, &us1000BaseT); | ||
1189 | MiRead(pAdapter, PHY_PHY_STATUS, &usVmiPhyStatus); | ||
1190 | MiRead(pAdapter, PHY_CONTROL, &usControl); | ||
1191 | |||
1192 | if (ucLinkStatus) { | ||
1193 | *ucLinkStatus = | ||
1194 | (unsigned char)((usVmiPhyStatus & 0x0040) ? 1 : 0); | ||
1195 | } | ||
1196 | |||
1197 | if (uiAutoNeg) { | ||
1198 | *uiAutoNeg = | ||
1199 | (usControl & 0x1000) ? ((usVmiPhyStatus & 0x0020) ? | ||
1200 | TRUEPHY_ANEG_COMPLETE : | ||
1201 | TRUEPHY_ANEG_NOT_COMPLETE) : | ||
1202 | TRUEPHY_ANEG_DISABLED; | ||
1203 | } | ||
1204 | |||
1205 | if (uiLinkSpeed) { | ||
1206 | *uiLinkSpeed = (usVmiPhyStatus & 0x0300) >> 8; | ||
1207 | } | ||
1208 | |||
1209 | if (uiDuplexMode) { | ||
1210 | *uiDuplexMode = (usVmiPhyStatus & 0x0080) >> 7; | ||
1211 | } | ||
1212 | |||
1213 | if (uiMdiMdix) { | ||
1214 | /* NOTE: Need to complete this */ | ||
1215 | *uiMdiMdix = 0; | ||
1216 | } | ||
1217 | |||
1218 | if (uiMasterSlave) { | ||
1219 | *uiMasterSlave = | ||
1220 | (us1000BaseT & 0x4000) ? TRUEPHY_CFG_MASTER : | ||
1221 | TRUEPHY_CFG_SLAVE; | ||
1222 | } | ||
1223 | |||
1224 | if (uiPolarity) { | ||
1225 | *uiPolarity = | ||
1226 | (usVmiPhyStatus & 0x0400) ? TRUEPHY_POLARITY_INVERTED : | ||
1227 | TRUEPHY_POLARITY_NORMAL; | ||
1228 | } | ||
1229 | } | ||
1230 | |||
1231 | void ET1310_PhyAndOrReg(struct et131x_adapter *pAdapter, | ||
1232 | uint16_t regnum, uint16_t andMask, uint16_t orMask) | ||
1233 | { | ||
1234 | uint16_t reg; | ||
1235 | |||
1236 | // Read the requested register | ||
1237 | MiRead(pAdapter, regnum, ®); | ||
1238 | |||
1239 | // Apply the AND mask | ||
1240 | reg &= andMask; | ||
1241 | |||
1242 | // Apply the OR mask | ||
1243 | reg |= orMask; | ||
1244 | |||
1245 | // Write the value back to the register | ||
1246 | MiWrite(pAdapter, regnum, reg); | ||
1247 | } | ||
1248 | |||
1249 | void ET1310_PhyAccessMiBit(struct et131x_adapter *pAdapter, uint16_t action, | ||
1250 | uint16_t regnum, uint16_t bitnum, uint8_t *value) | ||
1251 | { | ||
1252 | uint16_t reg; | ||
1253 | uint16_t mask = 0; | ||
1254 | |||
1255 | // Create a mask to isolate the requested bit | ||
1256 | mask = 0x0001 << bitnum; | ||
1257 | |||
1258 | // Read the requested register | ||
1259 | MiRead(pAdapter, regnum, ®); | ||
1260 | |||
1261 | switch (action) { | ||
1262 | case TRUEPHY_BIT_READ: | ||
1263 | if (value != NULL) { | ||
1264 | *value = (reg & mask) >> bitnum; | ||
1265 | } | ||
1266 | break; | ||
1267 | |||
1268 | case TRUEPHY_BIT_SET: | ||
1269 | reg |= mask; | ||
1270 | MiWrite(pAdapter, regnum, reg); | ||
1271 | break; | ||
1272 | |||
1273 | case TRUEPHY_BIT_CLEAR: | ||
1274 | reg &= ~mask; | ||
1275 | MiWrite(pAdapter, regnum, reg); | ||
1276 | break; | ||
1277 | |||
1278 | default: | ||
1279 | break; | ||
1280 | } | ||
1281 | } | ||
diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h new file mode 100644 index 000000000000..d624cbbadbd7 --- /dev/null +++ b/drivers/staging/et131x/et1310_phy.h | |||
@@ -0,0 +1,910 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_phy.h - Defines, structs, enums, prototypes, etc. pertaining to the | ||
12 | * PHY. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef _ET1310_PHY_H_ | ||
60 | #define _ET1310_PHY_H_ | ||
61 | |||
62 | #include "et1310_address_map.h" | ||
63 | |||
64 | #define TRUEPHY_SUCCESS 0 | ||
65 | #define TRUEPHY_FAILURE 1 | ||
66 | typedef void *TRUEPHY_HANDLE; | ||
67 | typedef void *TRUEPHY_PLATFORM_HANDLE; | ||
68 | typedef void *TRUEPHY_OSAL_HANDLE; | ||
69 | |||
70 | /* MI Register Addresses */ | ||
71 | #define MI_CONTROL_REG 0 | ||
72 | #define MI_STATUS_REG 1 | ||
73 | #define MI_PHY_IDENTIFIER_1_REG 2 | ||
74 | #define MI_PHY_IDENTIFIER_2_REG 3 | ||
75 | #define MI_AUTONEG_ADVERTISEMENT_REG 4 | ||
76 | #define MI_AUTONEG_LINK_PARTNER_ABILITY_REG 5 | ||
77 | #define MI_AUTONEG_EXPANSION_REG 6 | ||
78 | #define MI_AUTONEG_NEXT_PAGE_TRANSMIT_REG 7 | ||
79 | #define MI_LINK_PARTNER_NEXT_PAGE_REG 8 | ||
80 | #define MI_1000BASET_CONTROL_REG 9 | ||
81 | #define MI_1000BASET_STATUS_REG 10 | ||
82 | #define MI_RESERVED11_REG 11 | ||
83 | #define MI_RESERVED12_REG 12 | ||
84 | #define MI_RESERVED13_REG 13 | ||
85 | #define MI_RESERVED14_REG 14 | ||
86 | #define MI_EXTENDED_STATUS_REG 15 | ||
87 | |||
88 | /* VMI Register Addresses */ | ||
89 | #define VMI_RESERVED16_REG 16 | ||
90 | #define VMI_RESERVED17_REG 17 | ||
91 | #define VMI_RESERVED18_REG 18 | ||
92 | #define VMI_LOOPBACK_CONTROL_REG 19 | ||
93 | #define VMI_RESERVED20_REG 20 | ||
94 | #define VMI_MI_CONTROL_REG 21 | ||
95 | #define VMI_PHY_CONFIGURATION_REG 22 | ||
96 | #define VMI_PHY_CONTROL_REG 23 | ||
97 | #define VMI_INTERRUPT_MASK_REG 24 | ||
98 | #define VMI_INTERRUPT_STATUS_REG 25 | ||
99 | #define VMI_PHY_STATUS_REG 26 | ||
100 | #define VMI_LED_CONTROL_1_REG 27 | ||
101 | #define VMI_LED_CONTROL_2_REG 28 | ||
102 | #define VMI_RESERVED29_REG 29 | ||
103 | #define VMI_RESERVED30_REG 30 | ||
104 | #define VMI_RESERVED31_REG 31 | ||
105 | |||
106 | /* PHY Register Mapping(MI) Management Interface Regs */ | ||
107 | typedef struct _MI_REGS_t { | ||
108 | u8 bmcr; // Basic mode control reg(Reg 0x00) | ||
109 | u8 bmsr; // Basic mode status reg(Reg 0x01) | ||
110 | u8 idr1; // Phy identifier reg 1(Reg 0x02) | ||
111 | u8 idr2; // Phy identifier reg 2(Reg 0x03) | ||
112 | u8 anar; // Auto-Negotiation advertisement(Reg 0x04) | ||
113 | u8 anlpar; // Auto-Negotiation link Partner Ability(Reg 0x05) | ||
114 | u8 aner; // Auto-Negotiation expansion reg(Reg 0x06) | ||
115 | u8 annptr; // Auto-Negotiation next page transmit reg(Reg 0x07) | ||
116 | u8 lpnpr; // link partner next page reg(Reg 0x08) | ||
117 | u8 gcr; // Gigabit basic mode control reg(Reg 0x09) | ||
118 | u8 gsr; // Gigabit basic mode status reg(Reg 0x0A) | ||
119 | u8 mi_res1[4]; // Future use by MI working group(Reg 0x0B - 0x0E) | ||
120 | u8 esr; // Extended status reg(Reg 0x0F) | ||
121 | u8 mi_res2[3]; // Future use by MI working group(Reg 0x10 - 0x12) | ||
122 | u8 loop_ctl; // Loopback Control Reg(Reg 0x13) | ||
123 | u8 mi_res3; // Future use by MI working group(Reg 0x14) | ||
124 | u8 mcr; // MI Control Reg(Reg 0x15) | ||
125 | u8 pcr; // Configuration Reg(Reg 0x16) | ||
126 | u8 phy_ctl; // PHY Control Reg(Reg 0x17) | ||
127 | u8 imr; // Interrupt Mask Reg(Reg 0x18) | ||
128 | u8 isr; // Interrupt Status Reg(Reg 0x19) | ||
129 | u8 psr; // PHY Status Reg(Reg 0x1A) | ||
130 | u8 lcr1; // LED Control 1 Reg(Reg 0x1B) | ||
131 | u8 lcr2; // LED Control 2 Reg(Reg 0x1C) | ||
132 | u8 mi_res4[3]; // Future use by MI working group(Reg 0x1D - 0x1F) | ||
133 | } MI_REGS_t, *PMI_REGS_t; | ||
134 | |||
135 | /* MI Register 0: Basic mode control register */ | ||
136 | typedef union _MI_BMCR_t { | ||
137 | u16 value; | ||
138 | struct { | ||
139 | #ifdef _BIT_FIELDS_HTOL | ||
140 | u16 reset:1; // bit 15 | ||
141 | u16 loopback:1; // bit 14 | ||
142 | u16 speed_sel:1; // bit 13 | ||
143 | u16 enable_autoneg:1; // bit 12 | ||
144 | u16 power_down:1; // bit 11 | ||
145 | u16 isolate:1; // bit 10 | ||
146 | u16 restart_autoneg:1; // bit 9 | ||
147 | u16 duplex_mode:1; // bit 8 | ||
148 | u16 col_test:1; // bit 7 | ||
149 | u16 speed_1000_sel:1; // bit 6 | ||
150 | u16 res1:6; // bits 0-5 | ||
151 | #else | ||
152 | u16 res1:6; // bits 0-5 | ||
153 | u16 speed_1000_sel:1; // bit 6 | ||
154 | u16 col_test:1; // bit 7 | ||
155 | u16 duplex_mode:1; // bit 8 | ||
156 | u16 restart_autoneg:1; // bit 9 | ||
157 | u16 isolate:1; // bit 10 | ||
158 | u16 power_down:1; // bit 11 | ||
159 | u16 enable_autoneg:1; // bit 12 | ||
160 | u16 speed_sel:1; // bit 13 | ||
161 | u16 loopback:1; // bit 14 | ||
162 | u16 reset:1; // bit 15 | ||
163 | #endif | ||
164 | } bits; | ||
165 | } MI_BMCR_t, *PMI_BMCR_t; | ||
166 | |||
167 | /* MI Register 1: Basic mode status register */ | ||
168 | typedef union _MI_BMSR_t { | ||
169 | u16 value; | ||
170 | struct { | ||
171 | #ifdef _BIT_FIELDS_HTOL | ||
172 | u16 link_100T4:1; // bit 15 | ||
173 | u16 link_100fdx:1; // bit 14 | ||
174 | u16 link_100hdx:1; // bit 13 | ||
175 | u16 link_10fdx:1; // bit 12 | ||
176 | u16 link_10hdx:1; // bit 11 | ||
177 | u16 link_100T2fdx:1; // bit 10 | ||
178 | u16 link_100T2hdx:1; // bit 9 | ||
179 | u16 extend_status:1; // bit 8 | ||
180 | u16 res1:1; // bit 7 | ||
181 | u16 preamble_supress:1; // bit 6 | ||
182 | u16 auto_neg_complete:1; // bit 5 | ||
183 | u16 remote_fault:1; // bit 4 | ||
184 | u16 auto_neg_able:1; // bit 3 | ||
185 | u16 link_status:1; // bit 2 | ||
186 | u16 jabber_detect:1; // bit 1 | ||
187 | u16 ext_cap:1; // bit 0 | ||
188 | #else | ||
189 | u16 ext_cap:1; // bit 0 | ||
190 | u16 jabber_detect:1; // bit 1 | ||
191 | u16 link_status:1; // bit 2 | ||
192 | u16 auto_neg_able:1; // bit 3 | ||
193 | u16 remote_fault:1; // bit 4 | ||
194 | u16 auto_neg_complete:1; // bit 5 | ||
195 | u16 preamble_supress:1; // bit 6 | ||
196 | u16 res1:1; // bit 7 | ||
197 | u16 extend_status:1; // bit 8 | ||
198 | u16 link_100T2hdx:1; // bit 9 | ||
199 | u16 link_100T2fdx:1; // bit 10 | ||
200 | u16 link_10hdx:1; // bit 11 | ||
201 | u16 link_10fdx:1; // bit 12 | ||
202 | u16 link_100hdx:1; // bit 13 | ||
203 | u16 link_100fdx:1; // bit 14 | ||
204 | u16 link_100T4:1; // bit 15 | ||
205 | #endif | ||
206 | } bits; | ||
207 | } MI_BMSR_t, *PMI_BMSR_t; | ||
208 | |||
209 | /* MI Register 2: Physical Identifier 1 */ | ||
210 | typedef union _MI_IDR1_t { | ||
211 | u16 value; | ||
212 | struct { | ||
213 | u16 ieee_address:16; // 0x0282 default(bits 0-15) | ||
214 | } bits; | ||
215 | } MI_IDR1_t, *PMI_IDR1_t; | ||
216 | |||
217 | /* MI Register 3: Physical Identifier 2 */ | ||
218 | typedef union _MI_IDR2_t { | ||
219 | u16 value; | ||
220 | struct { | ||
221 | #ifdef _BIT_FIELDS_HTOL | ||
222 | u16 ieee_address:6; // 111100 default(bits 10-15) | ||
223 | u16 model_no:6; // 000001 default(bits 4-9) | ||
224 | u16 rev_no:4; // 0010 default(bits 0-3) | ||
225 | #else | ||
226 | u16 rev_no:4; // 0010 default(bits 0-3) | ||
227 | u16 model_no:6; // 000001 default(bits 4-9) | ||
228 | u16 ieee_address:6; // 111100 default(bits 10-15) | ||
229 | #endif | ||
230 | } bits; | ||
231 | } MI_IDR2_t, *PMI_IDR2_t; | ||
232 | |||
233 | /* MI Register 4: Auto-negotiation advertisement register */ | ||
234 | typedef union _MI_ANAR_t { | ||
235 | u16 value; | ||
236 | struct { | ||
237 | #ifdef _BIT_FIELDS_HTOL | ||
238 | u16 np_indication:1; // bit 15 | ||
239 | u16 res2:1; // bit 14 | ||
240 | u16 remote_fault:1; // bit 13 | ||
241 | u16 res1:1; // bit 12 | ||
242 | u16 cap_asmpause:1; // bit 11 | ||
243 | u16 cap_pause:1; // bit 10 | ||
244 | u16 cap_100T4:1; // bit 9 | ||
245 | u16 cap_100fdx:1; // bit 8 | ||
246 | u16 cap_100hdx:1; // bit 7 | ||
247 | u16 cap_10fdx:1; // bit 6 | ||
248 | u16 cap_10hdx:1; // bit 5 | ||
249 | u16 selector:5; // bits 0-4 | ||
250 | #else | ||
251 | u16 selector:5; // bits 0-4 | ||
252 | u16 cap_10hdx:1; // bit 5 | ||
253 | u16 cap_10fdx:1; // bit 6 | ||
254 | u16 cap_100hdx:1; // bit 7 | ||
255 | u16 cap_100fdx:1; // bit 8 | ||
256 | u16 cap_100T4:1; // bit 9 | ||
257 | u16 cap_pause:1; // bit 10 | ||
258 | u16 cap_asmpause:1; // bit 11 | ||
259 | u16 res1:1; // bit 12 | ||
260 | u16 remote_fault:1; // bit 13 | ||
261 | u16 res2:1; // bit 14 | ||
262 | u16 np_indication:1; // bit 15 | ||
263 | #endif | ||
264 | } bits; | ||
265 | } MI_ANAR_t, *PMI_ANAR_t; | ||
266 | |||
267 | /* MI Register 5: Auto-negotiation link partner advertisement register */ | ||
268 | typedef struct _MI_ANLPAR_t { | ||
269 | u16 value; | ||
270 | struct { | ||
271 | #ifdef _BIT_FIELDS_HTOL | ||
272 | u16 np_indication:1; // bit 15 | ||
273 | u16 acknowledge:1; // bit 14 | ||
274 | u16 remote_fault:1; // bit 13 | ||
275 | u16 res1:1; // bit 12 | ||
276 | u16 cap_asmpause:1; // bit 11 | ||
277 | u16 cap_pause:1; // bit 10 | ||
278 | u16 cap_100T4:1; // bit 9 | ||
279 | u16 cap_100fdx:1; // bit 8 | ||
280 | u16 cap_100hdx:1; // bit 7 | ||
281 | u16 cap_10fdx:1; // bit 6 | ||
282 | u16 cap_10hdx:1; // bit 5 | ||
283 | u16 selector:5; // bits 0-4 | ||
284 | #else | ||
285 | u16 selector:5; // bits 0-4 | ||
286 | u16 cap_10hdx:1; // bit 5 | ||
287 | u16 cap_10fdx:1; // bit 6 | ||
288 | u16 cap_100hdx:1; // bit 7 | ||
289 | u16 cap_100fdx:1; // bit 8 | ||
290 | u16 cap_100T4:1; // bit 9 | ||
291 | u16 cap_pause:1; // bit 10 | ||
292 | u16 cap_asmpause:1; // bit 11 | ||
293 | u16 res1:1; // bit 12 | ||
294 | u16 remote_fault:1; // bit 13 | ||
295 | u16 acknowledge:1; // bit 14 | ||
296 | u16 np_indication:1; // bit 15 | ||
297 | #endif | ||
298 | } bits; | ||
299 | } MI_ANLPAR_t, *PMI_ANLPAR_t; | ||
300 | |||
301 | /* MI Register 6: Auto-negotiation expansion register */ | ||
302 | typedef union _MI_ANER_t { | ||
303 | u16 value; | ||
304 | struct { | ||
305 | #ifdef _BIT_FIELDS_HTOL | ||
306 | u16 res:11; // bits 5-15 | ||
307 | u16 pdf:1; // bit 4 | ||
308 | u16 lp_np_able:1; // bit 3 | ||
309 | u16 np_able:1; // bit 2 | ||
310 | u16 page_rx:1; // bit 1 | ||
311 | u16 lp_an_able:1; // bit 0 | ||
312 | #else | ||
313 | u16 lp_an_able:1; // bit 0 | ||
314 | u16 page_rx:1; // bit 1 | ||
315 | u16 np_able:1; // bit 2 | ||
316 | u16 lp_np_able:1; // bit 3 | ||
317 | u16 pdf:1; // bit 4 | ||
318 | u16 res:11; // bits 5-15 | ||
319 | #endif | ||
320 | } bits; | ||
321 | } MI_ANER_t, *PMI_ANER_t; | ||
322 | |||
323 | /* MI Register 7: Auto-negotiation next page transmit reg(0x07) */ | ||
324 | typedef union _MI_ANNPTR_t { | ||
325 | u16 value; | ||
326 | struct { | ||
327 | #ifdef _BIT_FIELDS_HTOL | ||
328 | u16 np:1; // bit 15 | ||
329 | u16 res1:1; // bit 14 | ||
330 | u16 msg_page:1; // bit 13 | ||
331 | u16 ack2:1; // bit 12 | ||
332 | u16 toggle:1; // bit 11 | ||
333 | u16 msg:11; // bits 0-10 | ||
334 | #else | ||
335 | u16 msg:11; // bits 0-10 | ||
336 | u16 toggle:1; // bit 11 | ||
337 | u16 ack2:1; // bit 12 | ||
338 | u16 msg_page:1; // bit 13 | ||
339 | u16 res1:1; // bit 14 | ||
340 | u16 np:1; // bit 15 | ||
341 | #endif | ||
342 | } bits; | ||
343 | } MI_ANNPTR_t, *PMI_ANNPTR_t; | ||
344 | |||
345 | /* MI Register 8: Link Partner Next Page Reg(0x08) */ | ||
346 | typedef union _MI_LPNPR_t { | ||
347 | u16 value; | ||
348 | struct { | ||
349 | #ifdef _BIT_FIELDS_HTOL | ||
350 | u16 np:1; // bit 15 | ||
351 | u16 ack:1; // bit 14 | ||
352 | u16 msg_page:1; // bit 13 | ||
353 | u16 ack2:1; // bit 12 | ||
354 | u16 toggle:1; // bit 11 | ||
355 | u16 msg:11; // bits 0-10 | ||
356 | #else | ||
357 | u16 msg:11; // bits 0-10 | ||
358 | u16 toggle:1; // bit 11 | ||
359 | u16 ack2:1; // bit 12 | ||
360 | u16 msg_page:1; // bit 13 | ||
361 | u16 ack:1; // bit 14 | ||
362 | u16 np:1; // bit 15 | ||
363 | #endif | ||
364 | } bits; | ||
365 | } MI_LPNPR_t, *PMI_LPNPR_t; | ||
366 | |||
367 | /* MI Register 9: 1000BaseT Control Reg(0x09) */ | ||
368 | typedef union _MI_GCR_t { | ||
369 | u16 value; | ||
370 | struct { | ||
371 | #ifdef _BIT_FIELDS_HTOL | ||
372 | u16 test_mode:3; // bits 13-15 | ||
373 | u16 ms_config_en:1; // bit 12 | ||
374 | u16 ms_value:1; // bit 11 | ||
375 | u16 port_type:1; // bit 10 | ||
376 | u16 link_1000fdx:1; // bit 9 | ||
377 | u16 link_1000hdx:1; // bit 8 | ||
378 | u16 res:8; // bit 0-7 | ||
379 | #else | ||
380 | u16 res:8; // bit 0-7 | ||
381 | u16 link_1000hdx:1; // bit 8 | ||
382 | u16 link_1000fdx:1; // bit 9 | ||
383 | u16 port_type:1; // bit 10 | ||
384 | u16 ms_value:1; // bit 11 | ||
385 | u16 ms_config_en:1; // bit 12 | ||
386 | u16 test_mode:3; // bits 13-15 | ||
387 | #endif | ||
388 | } bits; | ||
389 | } MI_GCR_t, *PMI_GCR_t; | ||
390 | |||
391 | /* MI Register 10: 1000BaseT Status Reg(0x0A) */ | ||
392 | typedef union _MI_GSR_t { | ||
393 | u16 value; | ||
394 | struct { | ||
395 | #ifdef _BIT_FIELDS_HTOL | ||
396 | u16 ms_config_fault:1; // bit 15 | ||
397 | u16 ms_resolve:1; // bit 14 | ||
398 | u16 local_rx_status:1; // bit 13 | ||
399 | u16 remote_rx_status:1; // bit 12 | ||
400 | u16 link_1000fdx:1; // bit 11 | ||
401 | u16 link_1000hdx:1; // bit 10 | ||
402 | u16 res:2; // bits 8-9 | ||
403 | u16 idle_err_cnt:8; // bits 0-7 | ||
404 | #else | ||
405 | u16 idle_err_cnt:8; // bits 0-7 | ||
406 | u16 res:2; // bits 8-9 | ||
407 | u16 link_1000hdx:1; // bit 10 | ||
408 | u16 link_1000fdx:1; // bit 11 | ||
409 | u16 remote_rx_status:1; // bit 12 | ||
410 | u16 local_rx_status:1; // bit 13 | ||
411 | u16 ms_resolve:1; // bit 14 | ||
412 | u16 ms_config_fault:1; // bit 15 | ||
413 | #endif | ||
414 | } bits; | ||
415 | } MI_GSR_t, *PMI_GSR_t; | ||
416 | |||
417 | /* MI Register 11 - 14: Reserved Regs(0x0B - 0x0E) */ | ||
418 | typedef union _MI_RES_t { | ||
419 | u16 value; | ||
420 | struct { | ||
421 | #ifdef _BIT_FIELDS_HTOL | ||
422 | u16 res15:1; // bit 15 | ||
423 | u16 res14:1; // bit 14 | ||
424 | u16 res13:1; // bit 13 | ||
425 | u16 res12:1; // bit 12 | ||
426 | u16 res11:1; // bit 11 | ||
427 | u16 res10:1; // bit 10 | ||
428 | u16 res9:1; // bit 9 | ||
429 | u16 res8:1; // bit 8 | ||
430 | u16 res7:1; // bit 7 | ||
431 | u16 res6:1; // bit 6 | ||
432 | u16 res5:1; // bit 5 | ||
433 | u16 res4:1; // bit 4 | ||
434 | u16 res3:1; // bit 3 | ||
435 | u16 res2:1; // bit 2 | ||
436 | u16 res1:1; // bit 1 | ||
437 | u16 res0:1; // bit 0 | ||
438 | #else | ||
439 | u16 res0:1; // bit 0 | ||
440 | u16 res1:1; // bit 1 | ||
441 | u16 res2:1; // bit 2 | ||
442 | u16 res3:1; // bit 3 | ||
443 | u16 res4:1; // bit 4 | ||
444 | u16 res5:1; // bit 5 | ||
445 | u16 res6:1; // bit 6 | ||
446 | u16 res7:1; // bit 7 | ||
447 | u16 res8:1; // bit 8 | ||
448 | u16 res9:1; // bit 9 | ||
449 | u16 res10:1; // bit 10 | ||
450 | u16 res11:1; // bit 11 | ||
451 | u16 res12:1; // bit 12 | ||
452 | u16 res13:1; // bit 13 | ||
453 | u16 res14:1; // bit 14 | ||
454 | u16 res15:1; // bit 15 | ||
455 | #endif | ||
456 | } bits; | ||
457 | } MI_RES_t, *PMI_RES_t; | ||
458 | |||
459 | /* MI Register 15: Extended status Reg(0x0F) */ | ||
460 | typedef union _MI_ESR_t { | ||
461 | u16 value; | ||
462 | struct { | ||
463 | #ifdef _BIT_FIELDS_HTOL | ||
464 | u16 link_1000Xfdx:1; // bit 15 | ||
465 | u16 link_1000Xhdx:1; // bit 14 | ||
466 | u16 link_1000fdx:1; // bit 13 | ||
467 | u16 link_1000hdx:1; // bit 12 | ||
468 | u16 res:12; // bit 0-11 | ||
469 | #else | ||
470 | u16 res:12; // bit 0-11 | ||
471 | u16 link_1000hdx:1; // bit 12 | ||
472 | u16 link_1000fdx:1; // bit 13 | ||
473 | u16 link_1000Xhdx:1; // bit 14 | ||
474 | u16 link_1000Xfdx:1; // bit 15 | ||
475 | #endif | ||
476 | } bits; | ||
477 | } MI_ESR_t, *PMI_ESR_t; | ||
478 | |||
479 | /* MI Register 16 - 18: Reserved Reg(0x10-0x12) */ | ||
480 | |||
481 | /* MI Register 19: Loopback Control Reg(0x13) */ | ||
482 | typedef union _MI_LCR_t { | ||
483 | u16 value; | ||
484 | struct { | ||
485 | #ifdef _BIT_FIELDS_HTOL | ||
486 | u16 mii_en:1; // bit 15 | ||
487 | u16 pcs_en:1; // bit 14 | ||
488 | u16 pmd_en:1; // bit 13 | ||
489 | u16 all_digital_en:1; // bit 12 | ||
490 | u16 replica_en:1; // bit 11 | ||
491 | u16 line_driver_en:1; // bit 10 | ||
492 | u16 res:10; // bit 0-9 | ||
493 | #else | ||
494 | u16 res:10; // bit 0-9 | ||
495 | u16 line_driver_en:1; // bit 10 | ||
496 | u16 replica_en:1; // bit 11 | ||
497 | u16 all_digital_en:1; // bit 12 | ||
498 | u16 pmd_en:1; // bit 13 | ||
499 | u16 pcs_en:1; // bit 14 | ||
500 | u16 mii_en:1; // bit 15 | ||
501 | #endif | ||
502 | } bits; | ||
503 | } MI_LCR_t, *PMI_LCR_t; | ||
504 | |||
505 | /* MI Register 20: Reserved Reg(0x14) */ | ||
506 | |||
507 | /* MI Register 21: Management Interface Control Reg(0x15) */ | ||
508 | typedef union _MI_MICR_t { | ||
509 | u16 value; | ||
510 | struct { | ||
511 | #ifdef _BIT_FIELDS_HTOL | ||
512 | u16 res1:5; // bits 11-15 | ||
513 | u16 mi_error_count:7; // bits 4-10 | ||
514 | u16 res2:1; // bit 3 | ||
515 | u16 ignore_10g_fr:1; // bit 2 | ||
516 | u16 res3:1; // bit 1 | ||
517 | u16 preamble_supress_en:1; // bit 0 | ||
518 | #else | ||
519 | u16 preamble_supress_en:1; // bit 0 | ||
520 | u16 res3:1; // bit 1 | ||
521 | u16 ignore_10g_fr:1; // bit 2 | ||
522 | u16 res2:1; // bit 3 | ||
523 | u16 mi_error_count:7; // bits 4-10 | ||
524 | u16 res1:5; // bits 11-15 | ||
525 | #endif | ||
526 | } bits; | ||
527 | } MI_MICR_t, *PMI_MICR_t; | ||
528 | |||
529 | /* MI Register 22: PHY Configuration Reg(0x16) */ | ||
530 | typedef union _MI_PHY_CONFIG_t { | ||
531 | u16 value; | ||
532 | struct { | ||
533 | #ifdef _BIT_FIELDS_HTOL | ||
534 | u16 crs_tx_en:1; // bit 15 | ||
535 | u16 res1:1; // bit 14 | ||
536 | u16 tx_fifo_depth:2; // bits 12-13 | ||
537 | u16 speed_downshift:2; // bits 10-11 | ||
538 | u16 pbi_detect:1; // bit 9 | ||
539 | u16 tbi_rate:1; // bit 8 | ||
540 | u16 alternate_np:1; // bit 7 | ||
541 | u16 group_mdio_en:1; // bit 6 | ||
542 | u16 tx_clock_en:1; // bit 5 | ||
543 | u16 sys_clock_en:1; // bit 4 | ||
544 | u16 res2:1; // bit 3 | ||
545 | u16 mac_if_mode:3; // bits 0-2 | ||
546 | #else | ||
547 | u16 mac_if_mode:3; // bits 0-2 | ||
548 | u16 res2:1; // bit 3 | ||
549 | u16 sys_clock_en:1; // bit 4 | ||
550 | u16 tx_clock_en:1; // bit 5 | ||
551 | u16 group_mdio_en:1; // bit 6 | ||
552 | u16 alternate_np:1; // bit 7 | ||
553 | u16 tbi_rate:1; // bit 8 | ||
554 | u16 pbi_detect:1; // bit 9 | ||
555 | u16 speed_downshift:2; // bits 10-11 | ||
556 | u16 tx_fifo_depth:2; // bits 12-13 | ||
557 | u16 res1:1; // bit 14 | ||
558 | u16 crs_tx_en:1; // bit 15 | ||
559 | #endif | ||
560 | } bits; | ||
561 | } MI_PHY_CONFIG_t, *PMI_PHY_CONFIG_t; | ||
562 | |||
563 | /* MI Register 23: PHY CONTROL Reg(0x17) */ | ||
564 | typedef union _MI_PHY_CONTROL_t { | ||
565 | u16 value; | ||
566 | struct { | ||
567 | #ifdef _BIT_FIELDS_HTOL | ||
568 | u16 res1:1; // bit 15 | ||
569 | u16 tdr_en:1; // bit 14 | ||
570 | u16 res2:1; // bit 13 | ||
571 | u16 downshift_attempts:2; // bits 11-12 | ||
572 | u16 res3:5; // bit 6-10 | ||
573 | u16 jabber_10baseT:1; // bit 5 | ||
574 | u16 sqe_10baseT:1; // bit 4 | ||
575 | u16 tp_loopback_10baseT:1; // bit 3 | ||
576 | u16 preamble_gen_en:1; // bit 2 | ||
577 | u16 res4:1; // bit 1 | ||
578 | u16 force_int:1; // bit 0 | ||
579 | #else | ||
580 | u16 force_int:1; // bit 0 | ||
581 | u16 res4:1; // bit 1 | ||
582 | u16 preamble_gen_en:1; // bit 2 | ||
583 | u16 tp_loopback_10baseT:1; // bit 3 | ||
584 | u16 sqe_10baseT:1; // bit 4 | ||
585 | u16 jabber_10baseT:1; // bit 5 | ||
586 | u16 res3:5; // bit 6-10 | ||
587 | u16 downshift_attempts:2; // bits 11-12 | ||
588 | u16 res2:1; // bit 13 | ||
589 | u16 tdr_en:1; // bit 14 | ||
590 | u16 res1:1; // bit 15 | ||
591 | #endif | ||
592 | } bits; | ||
593 | } MI_PHY_CONTROL_t, *PMI_PHY_CONTROL_t; | ||
594 | |||
595 | /* MI Register 24: Interrupt Mask Reg(0x18) */ | ||
596 | typedef union _MI_IMR_t { | ||
597 | u16 value; | ||
598 | struct { | ||
599 | #ifdef _BIT_FIELDS_HTOL | ||
600 | u16 res1:6; // bits 10-15 | ||
601 | u16 mdio_sync_lost:1; // bit 9 | ||
602 | u16 autoneg_status:1; // bit 8 | ||
603 | u16 hi_bit_err:1; // bit 7 | ||
604 | u16 np_rx:1; // bit 6 | ||
605 | u16 err_counter_full:1; // bit 5 | ||
606 | u16 fifo_over_underflow:1; // bit 4 | ||
607 | u16 rx_status:1; // bit 3 | ||
608 | u16 link_status:1; // bit 2 | ||
609 | u16 automatic_speed:1; // bit 1 | ||
610 | u16 int_en:1; // bit 0 | ||
611 | #else | ||
612 | u16 int_en:1; // bit 0 | ||
613 | u16 automatic_speed:1; // bit 1 | ||
614 | u16 link_status:1; // bit 2 | ||
615 | u16 rx_status:1; // bit 3 | ||
616 | u16 fifo_over_underflow:1; // bit 4 | ||
617 | u16 err_counter_full:1; // bit 5 | ||
618 | u16 np_rx:1; // bit 6 | ||
619 | u16 hi_bit_err:1; // bit 7 | ||
620 | u16 autoneg_status:1; // bit 8 | ||
621 | u16 mdio_sync_lost:1; // bit 9 | ||
622 | u16 res1:6; // bits 10-15 | ||
623 | #endif | ||
624 | } bits; | ||
625 | } MI_IMR_t, *PMI_IMR_t; | ||
626 | |||
627 | /* MI Register 25: Interrupt Status Reg(0x19) */ | ||
628 | typedef union _MI_ISR_t { | ||
629 | u16 value; | ||
630 | struct { | ||
631 | #ifdef _BIT_FIELDS_HTOL | ||
632 | u16 res1:6; // bits 10-15 | ||
633 | u16 mdio_sync_lost:1; // bit 9 | ||
634 | u16 autoneg_status:1; // bit 8 | ||
635 | u16 hi_bit_err:1; // bit 7 | ||
636 | u16 np_rx:1; // bit 6 | ||
637 | u16 err_counter_full:1; // bit 5 | ||
638 | u16 fifo_over_underflow:1; // bit 4 | ||
639 | u16 rx_status:1; // bit 3 | ||
640 | u16 link_status:1; // bit 2 | ||
641 | u16 automatic_speed:1; // bit 1 | ||
642 | u16 int_en:1; // bit 0 | ||
643 | #else | ||
644 | u16 int_en:1; // bit 0 | ||
645 | u16 automatic_speed:1; // bit 1 | ||
646 | u16 link_status:1; // bit 2 | ||
647 | u16 rx_status:1; // bit 3 | ||
648 | u16 fifo_over_underflow:1; // bit 4 | ||
649 | u16 err_counter_full:1; // bit 5 | ||
650 | u16 np_rx:1; // bit 6 | ||
651 | u16 hi_bit_err:1; // bit 7 | ||
652 | u16 autoneg_status:1; // bit 8 | ||
653 | u16 mdio_sync_lost:1; // bit 9 | ||
654 | u16 res1:6; // bits 10-15 | ||
655 | #endif | ||
656 | } bits; | ||
657 | } MI_ISR_t, *PMI_ISR_t; | ||
658 | |||
659 | /* MI Register 26: PHY Status Reg(0x1A) */ | ||
660 | typedef union _MI_PSR_t { | ||
661 | u16 value; | ||
662 | struct { | ||
663 | #ifdef _BIT_FIELDS_HTOL | ||
664 | u16 res1:1; // bit 15 | ||
665 | u16 autoneg_fault:2; // bit 13-14 | ||
666 | u16 autoneg_status:1; // bit 12 | ||
667 | u16 mdi_x_status:1; // bit 11 | ||
668 | u16 polarity_status:1; // bit 10 | ||
669 | u16 speed_status:2; // bits 8-9 | ||
670 | u16 duplex_status:1; // bit 7 | ||
671 | u16 link_status:1; // bit 6 | ||
672 | u16 tx_status:1; // bit 5 | ||
673 | u16 rx_status:1; // bit 4 | ||
674 | u16 collision_status:1; // bit 3 | ||
675 | u16 autoneg_en:1; // bit 2 | ||
676 | u16 pause_en:1; // bit 1 | ||
677 | u16 asymmetric_dir:1; // bit 0 | ||
678 | #else | ||
679 | u16 asymmetric_dir:1; // bit 0 | ||
680 | u16 pause_en:1; // bit 1 | ||
681 | u16 autoneg_en:1; // bit 2 | ||
682 | u16 collision_status:1; // bit 3 | ||
683 | u16 rx_status:1; // bit 4 | ||
684 | u16 tx_status:1; // bit 5 | ||
685 | u16 link_status:1; // bit 6 | ||
686 | u16 duplex_status:1; // bit 7 | ||
687 | u16 speed_status:2; // bits 8-9 | ||
688 | u16 polarity_status:1; // bit 10 | ||
689 | u16 mdi_x_status:1; // bit 11 | ||
690 | u16 autoneg_status:1; // bit 12 | ||
691 | u16 autoneg_fault:2; // bit 13-14 | ||
692 | u16 res1:1; // bit 15 | ||
693 | #endif | ||
694 | } bits; | ||
695 | } MI_PSR_t, *PMI_PSR_t; | ||
696 | |||
697 | /* MI Register 27: LED Control Reg 1(0x1B) */ | ||
698 | typedef union _MI_LCR1_t { | ||
699 | u16 value; | ||
700 | struct { | ||
701 | #ifdef _BIT_FIELDS_HTOL | ||
702 | u16 res1:2; // bits 14-15 | ||
703 | u16 led_dup_indicate:2; // bits 12-13 | ||
704 | u16 led_10baseT:2; // bits 10-11 | ||
705 | u16 led_collision:2; // bits 8-9 | ||
706 | u16 res2:2; // bits 6-7 | ||
707 | u16 res3:2; // bits 4-5 | ||
708 | u16 pulse_dur:2; // bits 2-3 | ||
709 | u16 pulse_stretch1:1; // bit 1 | ||
710 | u16 pulse_stretch0:1; // bit 0 | ||
711 | #else | ||
712 | u16 pulse_stretch0:1; // bit 0 | ||
713 | u16 pulse_stretch1:1; // bit 1 | ||
714 | u16 pulse_dur:2; // bits 2-3 | ||
715 | u16 res3:2; // bits 4-5 | ||
716 | u16 res2:2; // bits 6-7 | ||
717 | u16 led_collision:2; // bits 8-9 | ||
718 | u16 led_10baseT:2; // bits 10-11 | ||
719 | u16 led_dup_indicate:2; // bits 12-13 | ||
720 | u16 res1:2; // bits 14-15 | ||
721 | #endif | ||
722 | } bits; | ||
723 | } MI_LCR1_t, *PMI_LCR1_t; | ||
724 | |||
725 | /* MI Register 28: LED Control Reg 2(0x1C) */ | ||
726 | typedef union _MI_LCR2_t { | ||
727 | u16 value; | ||
728 | struct { | ||
729 | #ifdef _BIT_FIELDS_HTOL | ||
730 | u16 led_link:4; // bits 12-15 | ||
731 | u16 led_tx_rx:4; // bits 8-11 | ||
732 | u16 led_100BaseTX:4; // bits 4-7 | ||
733 | u16 led_1000BaseT:4; // bits 0-3 | ||
734 | #else | ||
735 | u16 led_1000BaseT:4; // bits 0-3 | ||
736 | u16 led_100BaseTX:4; // bits 4-7 | ||
737 | u16 led_tx_rx:4; // bits 8-11 | ||
738 | u16 led_link:4; // bits 12-15 | ||
739 | #endif | ||
740 | } bits; | ||
741 | } MI_LCR2_t, *PMI_LCR2_t; | ||
742 | |||
743 | /* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */ | ||
744 | |||
745 | /* TruePHY headers */ | ||
746 | typedef struct _TRUEPHY_ACCESS_MI_REGS_ { | ||
747 | TRUEPHY_HANDLE hTruePhy; | ||
748 | int32_t nPhyId; | ||
749 | u8 bReadWrite; | ||
750 | u8 *pbyRegs; | ||
751 | u8 *pwData; | ||
752 | int32_t nRegCount; | ||
753 | } TRUEPHY_ACCESS_MI_REGS, *PTRUEPHY_ACCESS_MI_REGS; | ||
754 | |||
755 | /* TruePHY headers */ | ||
756 | typedef struct _TAG_TPAL_ACCESS_MI_REGS_ { | ||
757 | u32 nPhyId; | ||
758 | u8 bReadWrite; | ||
759 | u32 nRegCount; | ||
760 | u16 Data[4096]; | ||
761 | u8 Regs[4096]; | ||
762 | } TPAL_ACCESS_MI_REGS, *PTPAL_ACCESS_MI_REGS; | ||
763 | |||
764 | |||
765 | typedef TRUEPHY_HANDLE TPAL_HANDLE; | ||
766 | |||
767 | /* Forward declaration of the private adapter structure */ | ||
768 | struct et131x_adapter; | ||
769 | |||
770 | /* OS Specific Functions*/ | ||
771 | void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *adapter); | ||
772 | void TPAL_SetPhy10FullDuplex(struct et131x_adapter *adapter); | ||
773 | void TPAL_SetPhy10Force(struct et131x_adapter *pAdapter); | ||
774 | void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *adapter); | ||
775 | void TPAL_SetPhy100FullDuplex(struct et131x_adapter *adapter); | ||
776 | void TPAL_SetPhy100Force(struct et131x_adapter *pAdapter); | ||
777 | void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *adapter); | ||
778 | void TPAL_SetPhyAutoNeg(struct et131x_adapter *adapter); | ||
779 | |||
780 | /* Prototypes for ET1310_phy.c */ | ||
781 | int et131x_xcvr_find(struct et131x_adapter *adapter); | ||
782 | int et131x_setphy_normal(struct et131x_adapter *adapter); | ||
783 | int32_t PhyMiRead(struct et131x_adapter *adapter, | ||
784 | u8 xcvrAddr, u8 xcvrReg, u16 *value); | ||
785 | |||
786 | /* static inline function does not work because et131x_adapter is not always | ||
787 | * defined | ||
788 | */ | ||
789 | #define MiRead(adapter, xcvrReg, value) \ | ||
790 | PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value)) | ||
791 | |||
792 | int32_t MiWrite(struct et131x_adapter *adapter, | ||
793 | u8 xcvReg, u16 value); | ||
794 | void et131x_Mii_check(struct et131x_adapter *pAdapter, | ||
795 | MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints); | ||
796 | |||
797 | /* This last is not strictly required (the driver could call the TPAL | ||
798 | * version instead), but this sets the adapter up correctly, and calls the | ||
799 | * access routine indirectly. This protects the driver from changes in TPAL. | ||
800 | */ | ||
801 | void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter); | ||
802 | |||
803 | /* Defines for PHY access routines */ | ||
804 | |||
805 | // Define bit operation flags | ||
806 | #define TRUEPHY_BIT_CLEAR 0 | ||
807 | #define TRUEPHY_BIT_SET 1 | ||
808 | #define TRUEPHY_BIT_READ 2 | ||
809 | |||
810 | // Define read/write operation flags | ||
811 | #ifndef TRUEPHY_READ | ||
812 | #define TRUEPHY_READ 0 | ||
813 | #define TRUEPHY_WRITE 1 | ||
814 | #define TRUEPHY_MASK 2 | ||
815 | #endif | ||
816 | |||
817 | // Define speeds | ||
818 | #define TRUEPHY_SPEED_10MBPS 0 | ||
819 | #define TRUEPHY_SPEED_100MBPS 1 | ||
820 | #define TRUEPHY_SPEED_1000MBPS 2 | ||
821 | |||
822 | // Define duplex modes | ||
823 | #define TRUEPHY_DUPLEX_HALF 0 | ||
824 | #define TRUEPHY_DUPLEX_FULL 1 | ||
825 | |||
826 | // Define master/slave configuration values | ||
827 | #define TRUEPHY_CFG_SLAVE 0 | ||
828 | #define TRUEPHY_CFG_MASTER 1 | ||
829 | |||
830 | // Define MDI/MDI-X settings | ||
831 | #define TRUEPHY_MDI 0 | ||
832 | #define TRUEPHY_MDIX 1 | ||
833 | #define TRUEPHY_AUTO_MDI_MDIX 2 | ||
834 | |||
835 | // Define 10Base-T link polarities | ||
836 | #define TRUEPHY_POLARITY_NORMAL 0 | ||
837 | #define TRUEPHY_POLARITY_INVERTED 1 | ||
838 | |||
839 | // Define auto-negotiation results | ||
840 | #define TRUEPHY_ANEG_NOT_COMPLETE 0 | ||
841 | #define TRUEPHY_ANEG_COMPLETE 1 | ||
842 | #define TRUEPHY_ANEG_DISABLED 2 | ||
843 | |||
844 | /* Define duplex advertisment flags */ | ||
845 | #define TRUEPHY_ADV_DUPLEX_NONE 0x00 | ||
846 | #define TRUEPHY_ADV_DUPLEX_FULL 0x01 | ||
847 | #define TRUEPHY_ADV_DUPLEX_HALF 0x02 | ||
848 | #define TRUEPHY_ADV_DUPLEX_BOTH \ | ||
849 | (TRUEPHY_ADV_DUPLEX_FULL | TRUEPHY_ADV_DUPLEX_HALF) | ||
850 | |||
851 | #define PHY_CONTROL 0x00 //#define TRU_MI_CONTROL_REGISTER 0 | ||
852 | #define PHY_STATUS 0x01 //#define TRU_MI_STATUS_REGISTER 1 | ||
853 | #define PHY_ID_1 0x02 //#define TRU_MI_PHY_IDENTIFIER_1_REGISTER 2 | ||
854 | #define PHY_ID_2 0x03 //#define TRU_MI_PHY_IDENTIFIER_2_REGISTER 3 | ||
855 | #define PHY_AUTO_ADVERTISEMENT 0x04 //#define TRU_MI_ADVERTISEMENT_REGISTER 4 | ||
856 | #define PHY_AUTO_LINK_PARTNER 0x05 //#define TRU_MI_LINK_PARTNER_ABILITY_REGISTER 5 | ||
857 | #define PHY_AUTO_EXPANSION 0x06 //#define TRU_MI_EXPANSION_REGISTER 6 | ||
858 | #define PHY_AUTO_NEXT_PAGE_TX 0x07 //#define TRU_MI_NEXT_PAGE_TRANSMIT_REGISTER 7 | ||
859 | #define PHY_LINK_PARTNER_NEXT_PAGE 0x08 //#define TRU_MI_LINK_PARTNER_NEXT_PAGE_REGISTER 8 | ||
860 | #define PHY_1000_CONTROL 0x09 //#define TRU_MI_1000BASET_CONTROL_REGISTER 9 | ||
861 | #define PHY_1000_STATUS 0x0A //#define TRU_MI_1000BASET_STATUS_REGISTER 10 | ||
862 | |||
863 | #define PHY_EXTENDED_STATUS 0x0F //#define TRU_MI_EXTENDED_STATUS_REGISTER 15 | ||
864 | |||
865 | // some defines for modem registers that seem to be 'reserved' | ||
866 | #define PHY_INDEX_REG 0x10 | ||
867 | #define PHY_DATA_REG 0x11 | ||
868 | |||
869 | #define PHY_MPHY_CONTROL_REG 0x12 //#define TRU_VMI_MPHY_CONTROL_REGISTER 18 | ||
870 | |||
871 | #define PHY_LOOPBACK_CONTROL 0x13 //#define TRU_VMI_LOOPBACK_CONTROL_1_REGISTER 19 | ||
872 | //#define TRU_VMI_LOOPBACK_CONTROL_2_REGISTER 20 | ||
873 | #define PHY_REGISTER_MGMT_CONTROL 0x15 //#define TRU_VMI_MI_SEQ_CONTROL_REGISTER 21 | ||
874 | #define PHY_CONFIG 0x16 //#define TRU_VMI_CONFIGURATION_REGISTER 22 | ||
875 | #define PHY_PHY_CONTROL 0x17 //#define TRU_VMI_PHY_CONTROL_REGISTER 23 | ||
876 | #define PHY_INTERRUPT_MASK 0x18 //#define TRU_VMI_INTERRUPT_MASK_REGISTER 24 | ||
877 | #define PHY_INTERRUPT_STATUS 0x19 //#define TRU_VMI_INTERRUPT_STATUS_REGISTER 25 | ||
878 | #define PHY_PHY_STATUS 0x1A //#define TRU_VMI_PHY_STATUS_REGISTER 26 | ||
879 | #define PHY_LED_1 0x1B //#define TRU_VMI_LED_CONTROL_1_REGISTER 27 | ||
880 | #define PHY_LED_2 0x1C //#define TRU_VMI_LED_CONTROL_2_REGISTER 28 | ||
881 | //#define TRU_VMI_LINK_CONTROL_REGISTER 29 | ||
882 | //#define TRU_VMI_TIMING_CONTROL_REGISTER | ||
883 | |||
884 | /* Prototypes for PHY access routines */ | ||
885 | void ET1310_PhyInit(struct et131x_adapter *adapter); | ||
886 | void ET1310_PhyReset(struct et131x_adapter *adapter); | ||
887 | void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down); | ||
888 | void ET1310_PhyAutoNeg(struct et131x_adapter *adapter, bool enable); | ||
889 | void ET1310_PhyDuplexMode(struct et131x_adapter *adapter, u16 duplex); | ||
890 | void ET1310_PhySpeedSelect(struct et131x_adapter *adapter, u16 speed); | ||
891 | void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter, | ||
892 | u16 duplex); | ||
893 | void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *adapter, | ||
894 | u16 duplex); | ||
895 | void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *adapter, | ||
896 | u16 duplex); | ||
897 | void ET1310_PhyLinkStatus(struct et131x_adapter *adapter, | ||
898 | u8 *ucLinkStatus, | ||
899 | u32 *uiAutoNeg, | ||
900 | u32 *uiLinkSpeed, | ||
901 | u32 *uiDuplexMode, | ||
902 | u32 *uiMdiMdix, | ||
903 | u32 *uiMasterSlave, u32 *uiPolarity); | ||
904 | void ET1310_PhyAndOrReg(struct et131x_adapter *adapter, | ||
905 | u16 regnum, u16 andMask, u16 orMask); | ||
906 | void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter, | ||
907 | u16 action, | ||
908 | u16 regnum, u16 bitnum, u8 *value); | ||
909 | |||
910 | #endif /* _ET1310_PHY_H_ */ | ||
diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c new file mode 100644 index 000000000000..9539bc628cae --- /dev/null +++ b/drivers/staging/et131x/et1310_pm.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_pm.c - All power management related code (not completely implemented) | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include "et131x_version.h" | ||
59 | #include "et131x_debug.h" | ||
60 | #include "et131x_defs.h" | ||
61 | |||
62 | #include <linux/init.h> | ||
63 | #include <linux/module.h> | ||
64 | #include <linux/types.h> | ||
65 | #include <linux/kernel.h> | ||
66 | |||
67 | #include <linux/sched.h> | ||
68 | #include <linux/ptrace.h> | ||
69 | #include <linux/slab.h> | ||
70 | #include <linux/ctype.h> | ||
71 | #include <linux/string.h> | ||
72 | #include <linux/timer.h> | ||
73 | #include <linux/interrupt.h> | ||
74 | #include <linux/in.h> | ||
75 | #include <linux/delay.h> | ||
76 | #include <asm/io.h> | ||
77 | #include <asm/system.h> | ||
78 | #include <asm/bitops.h> | ||
79 | |||
80 | #include <linux/netdevice.h> | ||
81 | #include <linux/etherdevice.h> | ||
82 | #include <linux/skbuff.h> | ||
83 | #include <linux/if_arp.h> | ||
84 | #include <linux/ioport.h> | ||
85 | |||
86 | #include "et1310_phy.h" | ||
87 | #include "et1310_pm.h" | ||
88 | #include "et1310_jagcore.h" | ||
89 | #include "et1310_mac.h" | ||
90 | #include "et1310_rx.h" | ||
91 | |||
92 | #include "et131x_adapter.h" | ||
93 | #include "et131x_initpci.h" | ||
94 | |||
95 | /* Data for debugging facilities */ | ||
96 | #ifdef CONFIG_ET131X_DEBUG | ||
97 | extern dbg_info_t *et131x_dbginfo; | ||
98 | #endif /* CONFIG_ET131X_DEBUG */ | ||
99 | |||
100 | /** | ||
101 | * EnablePhyComa - called when network cable is unplugged | ||
102 | * @pAdapter: pointer to our adapter structure | ||
103 | * | ||
104 | * driver receive an phy status change interrupt while in D0 and check that | ||
105 | * phy_status is down. | ||
106 | * | ||
107 | * -- gate off JAGCore; | ||
108 | * -- set gigE PHY in Coma mode | ||
109 | * -- wake on phy_interrupt; Perform software reset JAGCore, | ||
110 | * re-initialize jagcore and gigE PHY | ||
111 | * | ||
112 | * Add D0-ASPM-PhyLinkDown Support: | ||
113 | * -- while in D0, when there is a phy_interrupt indicating phy link | ||
114 | * down status, call the MPSetPhyComa routine to enter this active | ||
115 | * state power saving mode | ||
116 | * -- while in D0-ASPM-PhyLinkDown mode, when there is a phy_interrupt | ||
117 | * indicating linkup status, call the MPDisablePhyComa routine to | ||
118 | * restore JAGCore and gigE PHY | ||
119 | */ | ||
120 | void EnablePhyComa(struct et131x_adapter *pAdapter) | ||
121 | { | ||
122 | unsigned long lockflags; | ||
123 | PM_CSR_t GlobalPmCSR; | ||
124 | int32_t LoopCounter = 10; | ||
125 | |||
126 | DBG_ENTER(et131x_dbginfo); | ||
127 | |||
128 | GlobalPmCSR.value = readl(&pAdapter->CSRAddress->global.pm_csr.value); | ||
129 | |||
130 | /* Save the GbE PHY speed and duplex modes. Need to restore this | ||
131 | * when cable is plugged back in | ||
132 | */ | ||
133 | pAdapter->PoMgmt.PowerDownSpeed = pAdapter->AiForceSpeed; | ||
134 | pAdapter->PoMgmt.PowerDownDuplex = pAdapter->AiForceDpx; | ||
135 | |||
136 | /* Stop sending packets. */ | ||
137 | spin_lock_irqsave(&pAdapter->SendHWLock, lockflags); | ||
138 | MP_SET_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER); | ||
139 | spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags); | ||
140 | |||
141 | /* Wait for outstanding Receive packets */ | ||
142 | while ((MP_GET_RCV_REF(pAdapter) != 0) && (LoopCounter-- > 0)) { | ||
143 | mdelay(2); | ||
144 | } | ||
145 | |||
146 | /* Gate off JAGCore 3 clock domains */ | ||
147 | GlobalPmCSR.bits.pm_sysclk_gate = 0; | ||
148 | GlobalPmCSR.bits.pm_txclk_gate = 0; | ||
149 | GlobalPmCSR.bits.pm_rxclk_gate = 0; | ||
150 | writel(GlobalPmCSR.value, &pAdapter->CSRAddress->global.pm_csr.value); | ||
151 | |||
152 | /* Program gigE PHY in to Coma mode */ | ||
153 | GlobalPmCSR.bits.pm_phy_sw_coma = 1; | ||
154 | writel(GlobalPmCSR.value, &pAdapter->CSRAddress->global.pm_csr.value); | ||
155 | |||
156 | DBG_LEAVE(et131x_dbginfo); | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * DisablePhyComa - Disable the Phy Coma Mode | ||
161 | * @pAdapter: pointer to our adapter structure | ||
162 | */ | ||
163 | void DisablePhyComa(struct et131x_adapter *pAdapter) | ||
164 | { | ||
165 | PM_CSR_t GlobalPmCSR; | ||
166 | |||
167 | DBG_ENTER(et131x_dbginfo); | ||
168 | |||
169 | GlobalPmCSR.value = readl(&pAdapter->CSRAddress->global.pm_csr.value); | ||
170 | |||
171 | /* Disable phy_sw_coma register and re-enable JAGCore clocks */ | ||
172 | GlobalPmCSR.bits.pm_sysclk_gate = 1; | ||
173 | GlobalPmCSR.bits.pm_txclk_gate = 1; | ||
174 | GlobalPmCSR.bits.pm_rxclk_gate = 1; | ||
175 | GlobalPmCSR.bits.pm_phy_sw_coma = 0; | ||
176 | writel(GlobalPmCSR.value, &pAdapter->CSRAddress->global.pm_csr.value); | ||
177 | |||
178 | /* Restore the GbE PHY speed and duplex modes; | ||
179 | * Reset JAGCore; re-configure and initialize JAGCore and gigE PHY | ||
180 | */ | ||
181 | pAdapter->AiForceSpeed = pAdapter->PoMgmt.PowerDownSpeed; | ||
182 | pAdapter->AiForceDpx = pAdapter->PoMgmt.PowerDownDuplex; | ||
183 | |||
184 | /* Re-initialize the send structures */ | ||
185 | et131x_init_send(pAdapter); | ||
186 | |||
187 | /* Reset the RFD list and re-start RU */ | ||
188 | et131x_reset_recv(pAdapter); | ||
189 | |||
190 | /* Bring the device back to the state it was during init prior to | ||
191 | * autonegotiation being complete. This way, when we get the auto-neg | ||
192 | * complete interrupt, we can complete init by calling ConfigMacREGS2. | ||
193 | */ | ||
194 | et131x_soft_reset(pAdapter); | ||
195 | |||
196 | /* setup et1310 as per the documentation ?? */ | ||
197 | et131x_adapter_setup(pAdapter); | ||
198 | |||
199 | /* Allow Tx to restart */ | ||
200 | MP_CLEAR_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER); | ||
201 | |||
202 | /* Need to re-enable Rx. */ | ||
203 | et131x_rx_dma_enable(pAdapter); | ||
204 | |||
205 | DBG_LEAVE(et131x_dbginfo); | ||
206 | } | ||
207 | |||
diff --git a/drivers/staging/et131x/et1310_pm.h b/drivers/staging/et131x/et1310_pm.h new file mode 100644 index 000000000000..6802338e29d9 --- /dev/null +++ b/drivers/staging/et131x/et1310_pm.h | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_pm.h - Defines, structs, enums, prototypes, etc. pertaining to power | ||
12 | * management. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef _ET1310_PM_H_ | ||
60 | #define _ET1310_PM_H_ | ||
61 | |||
62 | #include "et1310_address_map.h" | ||
63 | |||
64 | #define MAX_WOL_PACKET_SIZE 0x80 | ||
65 | #define MAX_WOL_MASK_SIZE ( MAX_WOL_PACKET_SIZE / 8 ) | ||
66 | #define NUM_WOL_PATTERNS 0x5 | ||
67 | #define CRC16_POLY 0x1021 | ||
68 | |||
69 | /* Definition of NDIS_DEVICE_POWER_STATE */ | ||
70 | typedef enum { | ||
71 | NdisDeviceStateUnspecified = 0, | ||
72 | NdisDeviceStateD0, | ||
73 | NdisDeviceStateD1, | ||
74 | NdisDeviceStateD2, | ||
75 | NdisDeviceStateD3 | ||
76 | } NDIS_DEVICE_POWER_STATE; | ||
77 | |||
78 | typedef struct _MP_POWER_MGMT { | ||
79 | /* variable putting the phy into coma mode when boot up with no cable | ||
80 | * plugged in after 5 seconds | ||
81 | */ | ||
82 | u8 TransPhyComaModeOnBoot; | ||
83 | |||
84 | /* Array holding the five CRC values that the device is currently | ||
85 | * using for WOL. This will be queried when a pattern is to be | ||
86 | * removed. | ||
87 | */ | ||
88 | u32 localWolAndCrc0; | ||
89 | u16 WOLPatternList[NUM_WOL_PATTERNS]; | ||
90 | u8 WOLMaskList[NUM_WOL_PATTERNS][MAX_WOL_MASK_SIZE]; | ||
91 | u32 WOLMaskSize[NUM_WOL_PATTERNS]; | ||
92 | |||
93 | /* IP address */ | ||
94 | union { | ||
95 | u32 u32; | ||
96 | u8 u8[4]; | ||
97 | } IPAddress; | ||
98 | |||
99 | /* Current Power state of the adapter. */ | ||
100 | NDIS_DEVICE_POWER_STATE PowerState; | ||
101 | bool WOLState; | ||
102 | bool WOLEnabled; | ||
103 | bool Failed10Half; | ||
104 | bool bFailedStateTransition; | ||
105 | |||
106 | /* Next two used to save power information at power down. This | ||
107 | * information will be used during power up to set up parts of Power | ||
108 | * Management in JAGCore | ||
109 | */ | ||
110 | u32 tx_en; | ||
111 | u32 rx_en; | ||
112 | u16 PowerDownSpeed; | ||
113 | u8 PowerDownDuplex; | ||
114 | } MP_POWER_MGMT, *PMP_POWER_MGMT; | ||
115 | |||
116 | /* Forward declaration of the private adapter structure | ||
117 | * ( IS THERE A WAY TO DO THIS WITH A TYPEDEF??? ) | ||
118 | */ | ||
119 | struct et131x_adapter; | ||
120 | |||
121 | u16 CalculateCCITCRC16(u8 *Pattern, u8 *Mask, u32 MaskSize); | ||
122 | void EnablePhyComa(struct et131x_adapter *adapter); | ||
123 | void DisablePhyComa(struct et131x_adapter *adapter); | ||
124 | |||
125 | #endif /* _ET1310_PM_H_ */ | ||
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c new file mode 100644 index 000000000000..ec98da5da5bc --- /dev/null +++ b/drivers/staging/et131x/et1310_rx.c | |||
@@ -0,0 +1,1391 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_rx.c - Routines used to perform data reception | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include "et131x_version.h" | ||
59 | #include "et131x_debug.h" | ||
60 | #include "et131x_defs.h" | ||
61 | |||
62 | #include <linux/pci.h> | ||
63 | #include <linux/init.h> | ||
64 | #include <linux/module.h> | ||
65 | #include <linux/types.h> | ||
66 | #include <linux/kernel.h> | ||
67 | |||
68 | #include <linux/sched.h> | ||
69 | #include <linux/ptrace.h> | ||
70 | #include <linux/slab.h> | ||
71 | #include <linux/ctype.h> | ||
72 | #include <linux/string.h> | ||
73 | #include <linux/timer.h> | ||
74 | #include <linux/interrupt.h> | ||
75 | #include <linux/in.h> | ||
76 | #include <linux/delay.h> | ||
77 | #include <asm/io.h> | ||
78 | #include <asm/system.h> | ||
79 | #include <asm/bitops.h> | ||
80 | |||
81 | #include <linux/netdevice.h> | ||
82 | #include <linux/etherdevice.h> | ||
83 | #include <linux/skbuff.h> | ||
84 | #include <linux/if_arp.h> | ||
85 | #include <linux/ioport.h> | ||
86 | |||
87 | #include "et1310_phy.h" | ||
88 | #include "et1310_pm.h" | ||
89 | #include "et1310_jagcore.h" | ||
90 | |||
91 | #include "et131x_adapter.h" | ||
92 | #include "et131x_initpci.h" | ||
93 | |||
94 | #include "et1310_rx.h" | ||
95 | |||
96 | /* Data for debugging facilities */ | ||
97 | #ifdef CONFIG_ET131X_DEBUG | ||
98 | extern dbg_info_t *et131x_dbginfo; | ||
99 | #endif /* CONFIG_ET131X_DEBUG */ | ||
100 | |||
101 | |||
102 | void nic_return_rfd(struct et131x_adapter *pAdapter, PMP_RFD pMpRfd); | ||
103 | |||
104 | /** | ||
105 | * et131x_rx_dma_memory_alloc | ||
106 | * @adapter: pointer to our private adapter structure | ||
107 | * | ||
108 | * Returns 0 on success and errno on failure (as defined in errno.h) | ||
109 | * | ||
110 | * Allocates Free buffer ring 1 for sure, free buffer ring 0 if required, | ||
111 | * and the Packet Status Ring. | ||
112 | */ | ||
113 | int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) | ||
114 | { | ||
115 | uint32_t OuterLoop, InnerLoop; | ||
116 | uint32_t bufsize; | ||
117 | uint32_t pktStatRingSize, FBRChunkSize; | ||
118 | RX_RING_t *rx_ring; | ||
119 | |||
120 | DBG_ENTER(et131x_dbginfo); | ||
121 | |||
122 | /* Setup some convenience pointers */ | ||
123 | rx_ring = (RX_RING_t *) & adapter->RxRing; | ||
124 | |||
125 | /* Alloc memory for the lookup table */ | ||
126 | #ifdef USE_FBR0 | ||
127 | rx_ring->Fbr[0] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL); | ||
128 | #endif | ||
129 | |||
130 | rx_ring->Fbr[1] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL); | ||
131 | |||
132 | /* The first thing we will do is configure the sizes of the buffer | ||
133 | * rings. These will change based on jumbo packet support. Larger | ||
134 | * jumbo packets increases the size of each entry in FBR0, and the | ||
135 | * number of entries in FBR0, while at the same time decreasing the | ||
136 | * number of entries in FBR1. | ||
137 | * | ||
138 | * FBR1 holds "large" frames, FBR0 holds "small" frames. If FBR1 | ||
139 | * entries are huge in order to accomodate a "jumbo" frame, then it | ||
140 | * will have less entries. Conversely, FBR1 will now be relied upon | ||
141 | * to carry more "normal" frames, thus it's entry size also increases | ||
142 | * and the number of entries goes up too (since it now carries | ||
143 | * "small" + "regular" packets. | ||
144 | * | ||
145 | * In this scheme, we try to maintain 512 entries between the two | ||
146 | * rings. Also, FBR1 remains a constant size - when it's size doubles | ||
147 | * the number of entries halves. FBR0 increases in size, however. | ||
148 | */ | ||
149 | |||
150 | if (adapter->RegistryJumboPacket < 2048) { | ||
151 | #ifdef USE_FBR0 | ||
152 | rx_ring->Fbr0BufferSize = 256; | ||
153 | rx_ring->Fbr0NumEntries = 512; | ||
154 | #endif | ||
155 | rx_ring->Fbr1BufferSize = 2048; | ||
156 | rx_ring->Fbr1NumEntries = 512; | ||
157 | } else if (adapter->RegistryJumboPacket < 4096) { | ||
158 | #ifdef USE_FBR0 | ||
159 | rx_ring->Fbr0BufferSize = 512; | ||
160 | rx_ring->Fbr0NumEntries = 1024; | ||
161 | #endif | ||
162 | rx_ring->Fbr1BufferSize = 4096; | ||
163 | rx_ring->Fbr1NumEntries = 512; | ||
164 | } else { | ||
165 | #ifdef USE_FBR0 | ||
166 | rx_ring->Fbr0BufferSize = 1024; | ||
167 | rx_ring->Fbr0NumEntries = 768; | ||
168 | #endif | ||
169 | rx_ring->Fbr1BufferSize = 16384; | ||
170 | rx_ring->Fbr1NumEntries = 128; | ||
171 | } | ||
172 | |||
173 | #ifdef USE_FBR0 | ||
174 | adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr0NumEntries + | ||
175 | adapter->RxRing.Fbr1NumEntries; | ||
176 | #else | ||
177 | adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr1NumEntries; | ||
178 | #endif | ||
179 | |||
180 | /* Allocate an area of memory for Free Buffer Ring 1 */ | ||
181 | bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff; | ||
182 | rx_ring->pFbr1RingVa = pci_alloc_consistent(adapter->pdev, | ||
183 | bufsize, | ||
184 | &rx_ring->pFbr1RingPa); | ||
185 | if (!rx_ring->pFbr1RingVa) { | ||
186 | DBG_ERROR(et131x_dbginfo, | ||
187 | "Cannot alloc memory for Free Buffer Ring 1\n"); | ||
188 | DBG_LEAVE(et131x_dbginfo); | ||
189 | return -ENOMEM; | ||
190 | } | ||
191 | |||
192 | /* Save physical address | ||
193 | * | ||
194 | * NOTE: pci_alloc_consistent(), used above to alloc DMA regions, | ||
195 | * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses | ||
196 | * are ever returned, make sure the high part is retrieved here | ||
197 | * before storing the adjusted address. | ||
198 | */ | ||
199 | rx_ring->Fbr1Realpa = rx_ring->pFbr1RingPa; | ||
200 | |||
201 | /* Align Free Buffer Ring 1 on a 4K boundary */ | ||
202 | et131x_align_allocated_memory(adapter, | ||
203 | &rx_ring->Fbr1Realpa, | ||
204 | &rx_ring->Fbr1offset, 0x0FFF); | ||
205 | |||
206 | rx_ring->pFbr1RingVa = (void *)((uint8_t *) rx_ring->pFbr1RingVa + | ||
207 | rx_ring->Fbr1offset); | ||
208 | |||
209 | #ifdef USE_FBR0 | ||
210 | /* Allocate an area of memory for Free Buffer Ring 0 */ | ||
211 | bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff; | ||
212 | rx_ring->pFbr0RingVa = pci_alloc_consistent(adapter->pdev, | ||
213 | bufsize, | ||
214 | &rx_ring->pFbr0RingPa); | ||
215 | if (!rx_ring->pFbr0RingVa) { | ||
216 | DBG_ERROR(et131x_dbginfo, | ||
217 | "Cannot alloc memory for Free Buffer Ring 0\n"); | ||
218 | DBG_LEAVE(et131x_dbginfo); | ||
219 | return -ENOMEM; | ||
220 | } | ||
221 | |||
222 | /* Save physical address | ||
223 | * | ||
224 | * NOTE: pci_alloc_consistent(), used above to alloc DMA regions, | ||
225 | * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses | ||
226 | * are ever returned, make sure the high part is retrieved here before | ||
227 | * storing the adjusted address. | ||
228 | */ | ||
229 | rx_ring->Fbr0Realpa = rx_ring->pFbr0RingPa; | ||
230 | |||
231 | /* Align Free Buffer Ring 0 on a 4K boundary */ | ||
232 | et131x_align_allocated_memory(adapter, | ||
233 | &rx_ring->Fbr0Realpa, | ||
234 | &rx_ring->Fbr0offset, 0x0FFF); | ||
235 | |||
236 | rx_ring->pFbr0RingVa = (void *)((uint8_t *) rx_ring->pFbr0RingVa + | ||
237 | rx_ring->Fbr0offset); | ||
238 | #endif | ||
239 | |||
240 | for (OuterLoop = 0; OuterLoop < (rx_ring->Fbr1NumEntries / FBR_CHUNKS); | ||
241 | OuterLoop++) { | ||
242 | uint64_t Fbr1Offset; | ||
243 | uint64_t Fbr1TempPa; | ||
244 | uint32_t Fbr1Align; | ||
245 | |||
246 | /* This code allocates an area of memory big enough for N | ||
247 | * free buffers + (buffer_size - 1) so that the buffers can | ||
248 | * be aligned on 4k boundaries. If each buffer were aligned | ||
249 | * to a buffer_size boundary, the effect would be to double | ||
250 | * the size of FBR0. By allocating N buffers at once, we | ||
251 | * reduce this overhead. | ||
252 | */ | ||
253 | if (rx_ring->Fbr1BufferSize > 4096) { | ||
254 | Fbr1Align = 4096; | ||
255 | } else { | ||
256 | Fbr1Align = rx_ring->Fbr1BufferSize; | ||
257 | } | ||
258 | |||
259 | FBRChunkSize = | ||
260 | (FBR_CHUNKS * rx_ring->Fbr1BufferSize) + Fbr1Align - 1; | ||
261 | rx_ring->Fbr1MemVa[OuterLoop] = | ||
262 | pci_alloc_consistent(adapter->pdev, FBRChunkSize, | ||
263 | &rx_ring->Fbr1MemPa[OuterLoop]); | ||
264 | |||
265 | if (!rx_ring->Fbr1MemVa[OuterLoop]) { | ||
266 | DBG_ERROR(et131x_dbginfo, "Could not alloc memory\n"); | ||
267 | DBG_LEAVE(et131x_dbginfo); | ||
268 | return -ENOMEM; | ||
269 | } | ||
270 | |||
271 | /* See NOTE in "Save Physical Address" comment above */ | ||
272 | Fbr1TempPa = rx_ring->Fbr1MemPa[OuterLoop]; | ||
273 | |||
274 | et131x_align_allocated_memory(adapter, | ||
275 | &Fbr1TempPa, | ||
276 | &Fbr1Offset, (Fbr1Align - 1)); | ||
277 | |||
278 | for (InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++) { | ||
279 | uint32_t index = (OuterLoop * FBR_CHUNKS) + InnerLoop; | ||
280 | |||
281 | /* Save the Virtual address of this index for quick | ||
282 | * access later | ||
283 | */ | ||
284 | rx_ring->Fbr[1]->Va[index] = | ||
285 | (uint8_t *) rx_ring->Fbr1MemVa[OuterLoop] + | ||
286 | (InnerLoop * rx_ring->Fbr1BufferSize) + Fbr1Offset; | ||
287 | |||
288 | /* now store the physical address in the descriptor | ||
289 | * so the device can access it | ||
290 | */ | ||
291 | rx_ring->Fbr[1]->PAHigh[index] = | ||
292 | (uint32_t) (Fbr1TempPa >> 32); | ||
293 | rx_ring->Fbr[1]->PALow[index] = (uint32_t) Fbr1TempPa; | ||
294 | |||
295 | Fbr1TempPa += rx_ring->Fbr1BufferSize; | ||
296 | |||
297 | rx_ring->Fbr[1]->Buffer1[index] = | ||
298 | rx_ring->Fbr[1]->Va[index]; | ||
299 | rx_ring->Fbr[1]->Buffer2[index] = | ||
300 | rx_ring->Fbr[1]->Va[index] - 4; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | #ifdef USE_FBR0 | ||
305 | /* Same for FBR0 (if in use) */ | ||
306 | for (OuterLoop = 0; OuterLoop < (rx_ring->Fbr0NumEntries / FBR_CHUNKS); | ||
307 | OuterLoop++) { | ||
308 | uint64_t Fbr0Offset; | ||
309 | uint64_t Fbr0TempPa; | ||
310 | |||
311 | FBRChunkSize = ((FBR_CHUNKS + 1) * rx_ring->Fbr0BufferSize) - 1; | ||
312 | rx_ring->Fbr0MemVa[OuterLoop] = | ||
313 | pci_alloc_consistent(adapter->pdev, FBRChunkSize, | ||
314 | &rx_ring->Fbr0MemPa[OuterLoop]); | ||
315 | |||
316 | if (!rx_ring->Fbr0MemVa[OuterLoop]) { | ||
317 | DBG_ERROR(et131x_dbginfo, "Could not alloc memory\n"); | ||
318 | DBG_LEAVE(et131x_dbginfo); | ||
319 | return -ENOMEM; | ||
320 | } | ||
321 | |||
322 | /* See NOTE in "Save Physical Address" comment above */ | ||
323 | Fbr0TempPa = rx_ring->Fbr0MemPa[OuterLoop]; | ||
324 | |||
325 | et131x_align_allocated_memory(adapter, | ||
326 | &Fbr0TempPa, | ||
327 | &Fbr0Offset, | ||
328 | rx_ring->Fbr0BufferSize - 1); | ||
329 | |||
330 | for (InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++) { | ||
331 | uint32_t index = (OuterLoop * FBR_CHUNKS) + InnerLoop; | ||
332 | |||
333 | rx_ring->Fbr[0]->Va[index] = | ||
334 | (uint8_t *) rx_ring->Fbr0MemVa[OuterLoop] + | ||
335 | (InnerLoop * rx_ring->Fbr0BufferSize) + Fbr0Offset; | ||
336 | |||
337 | rx_ring->Fbr[0]->PAHigh[index] = | ||
338 | (uint32_t) (Fbr0TempPa >> 32); | ||
339 | rx_ring->Fbr[0]->PALow[index] = (uint32_t) Fbr0TempPa; | ||
340 | |||
341 | Fbr0TempPa += rx_ring->Fbr0BufferSize; | ||
342 | |||
343 | rx_ring->Fbr[0]->Buffer1[index] = | ||
344 | rx_ring->Fbr[0]->Va[index]; | ||
345 | rx_ring->Fbr[0]->Buffer2[index] = | ||
346 | rx_ring->Fbr[0]->Va[index] - 4; | ||
347 | } | ||
348 | } | ||
349 | #endif | ||
350 | |||
351 | /* Allocate an area of memory for FIFO of Packet Status ring entries */ | ||
352 | pktStatRingSize = | ||
353 | sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries; | ||
354 | |||
355 | rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev, | ||
356 | pktStatRingSize + 0x0fff, | ||
357 | &rx_ring->pPSRingPa); | ||
358 | |||
359 | if (!rx_ring->pPSRingVa) { | ||
360 | DBG_ERROR(et131x_dbginfo, | ||
361 | "Cannot alloc memory for Packet Status Ring\n"); | ||
362 | DBG_LEAVE(et131x_dbginfo); | ||
363 | return -ENOMEM; | ||
364 | } | ||
365 | |||
366 | /* Save physical address | ||
367 | * | ||
368 | * NOTE : pci_alloc_consistent(), used above to alloc DMA regions, | ||
369 | * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses | ||
370 | * are ever returned, make sure the high part is retrieved here before | ||
371 | * storing the adjusted address. | ||
372 | */ | ||
373 | rx_ring->pPSRingRealPa = rx_ring->pPSRingPa; | ||
374 | |||
375 | /* Align Packet Status Ring on a 4K boundary */ | ||
376 | et131x_align_allocated_memory(adapter, | ||
377 | &rx_ring->pPSRingRealPa, | ||
378 | &rx_ring->pPSRingOffset, 0x0FFF); | ||
379 | |||
380 | rx_ring->pPSRingVa = (void *)((uint8_t *) rx_ring->pPSRingVa + | ||
381 | rx_ring->pPSRingOffset); | ||
382 | |||
383 | /* Allocate an area of memory for writeback of status information */ | ||
384 | rx_ring->pRxStatusVa = pci_alloc_consistent(adapter->pdev, | ||
385 | sizeof(RX_STATUS_BLOCK_t) + | ||
386 | 0x7, &rx_ring->pRxStatusPa); | ||
387 | if (!rx_ring->pRxStatusVa) { | ||
388 | DBG_ERROR(et131x_dbginfo, | ||
389 | "Cannot alloc memory for Status Block\n"); | ||
390 | DBG_LEAVE(et131x_dbginfo); | ||
391 | return -ENOMEM; | ||
392 | } | ||
393 | |||
394 | /* Save physical address */ | ||
395 | rx_ring->RxStatusRealPA = rx_ring->pRxStatusPa; | ||
396 | |||
397 | /* Align write back on an 8 byte boundary */ | ||
398 | et131x_align_allocated_memory(adapter, | ||
399 | &rx_ring->RxStatusRealPA, | ||
400 | &rx_ring->RxStatusOffset, 0x07); | ||
401 | |||
402 | rx_ring->pRxStatusVa = (void *)((uint8_t *) rx_ring->pRxStatusVa + | ||
403 | rx_ring->RxStatusOffset); | ||
404 | rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD; | ||
405 | |||
406 | /* Recv | ||
407 | * pci_pool_create initializes a lookaside list. After successful | ||
408 | * creation, nonpaged fixed-size blocks can be allocated from and | ||
409 | * freed to the lookaside list. | ||
410 | * RFDs will be allocated from this pool. | ||
411 | */ | ||
412 | rx_ring->RecvLookaside = kmem_cache_create(adapter->netdev->name, | ||
413 | sizeof(MP_RFD), | ||
414 | 0, | ||
415 | SLAB_CACHE_DMA | | ||
416 | SLAB_HWCACHE_ALIGN, | ||
417 | NULL); | ||
418 | |||
419 | MP_SET_FLAG(adapter, fMP_ADAPTER_RECV_LOOKASIDE); | ||
420 | |||
421 | /* The RFDs are going to be put on lists later on, so initialize the | ||
422 | * lists now. | ||
423 | */ | ||
424 | INIT_LIST_HEAD(&rx_ring->RecvList); | ||
425 | INIT_LIST_HEAD(&rx_ring->RecvPendingList); | ||
426 | |||
427 | DBG_LEAVE(et131x_dbginfo); | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * et131x_rx_dma_memory_free - Free all memory allocated within this module. | ||
433 | * @adapter: pointer to our private adapter structure | ||
434 | */ | ||
435 | void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) | ||
436 | { | ||
437 | uint32_t index; | ||
438 | uint32_t bufsize; | ||
439 | uint32_t pktStatRingSize; | ||
440 | PMP_RFD pMpRfd; | ||
441 | RX_RING_t *rx_ring; | ||
442 | |||
443 | DBG_ENTER(et131x_dbginfo); | ||
444 | |||
445 | /* Setup some convenience pointers */ | ||
446 | rx_ring = (RX_RING_t *) & adapter->RxRing; | ||
447 | |||
448 | /* Free RFDs and associated packet descriptors */ | ||
449 | DBG_ASSERT(rx_ring->nReadyRecv == rx_ring->NumRfd); | ||
450 | |||
451 | while (!list_empty(&rx_ring->RecvList)) { | ||
452 | pMpRfd = (MP_RFD *) list_entry(rx_ring->RecvList.next, | ||
453 | MP_RFD, list_node); | ||
454 | |||
455 | list_del(&pMpRfd->list_node); | ||
456 | et131x_rfd_resources_free(adapter, pMpRfd); | ||
457 | } | ||
458 | |||
459 | while (!list_empty(&rx_ring->RecvPendingList)) { | ||
460 | pMpRfd = (MP_RFD *) list_entry(rx_ring->RecvPendingList.next, | ||
461 | MP_RFD, list_node); | ||
462 | list_del(&pMpRfd->list_node); | ||
463 | et131x_rfd_resources_free(adapter, pMpRfd); | ||
464 | } | ||
465 | |||
466 | /* Free Free Buffer Ring 1 */ | ||
467 | if (rx_ring->pFbr1RingVa) { | ||
468 | /* First the packet memory */ | ||
469 | for (index = 0; index < | ||
470 | (rx_ring->Fbr1NumEntries / FBR_CHUNKS); index++) { | ||
471 | if (rx_ring->Fbr1MemVa[index]) { | ||
472 | uint32_t Fbr1Align; | ||
473 | |||
474 | if (rx_ring->Fbr1BufferSize > 4096) { | ||
475 | Fbr1Align = 4096; | ||
476 | } else { | ||
477 | Fbr1Align = rx_ring->Fbr1BufferSize; | ||
478 | } | ||
479 | |||
480 | bufsize = | ||
481 | (rx_ring->Fbr1BufferSize * FBR_CHUNKS) + | ||
482 | Fbr1Align - 1; | ||
483 | |||
484 | pci_free_consistent(adapter->pdev, | ||
485 | bufsize, | ||
486 | rx_ring->Fbr1MemVa[index], | ||
487 | rx_ring->Fbr1MemPa[index]); | ||
488 | |||
489 | rx_ring->Fbr1MemVa[index] = NULL; | ||
490 | } | ||
491 | } | ||
492 | |||
493 | /* Now the FIFO itself */ | ||
494 | rx_ring->pFbr1RingVa = (void *)((uint8_t *) rx_ring->pFbr1RingVa - | ||
495 | rx_ring->Fbr1offset); | ||
496 | |||
497 | bufsize = | ||
498 | (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff; | ||
499 | |||
500 | pci_free_consistent(adapter->pdev, | ||
501 | bufsize, | ||
502 | rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa); | ||
503 | |||
504 | rx_ring->pFbr1RingVa = NULL; | ||
505 | } | ||
506 | |||
507 | #ifdef USE_FBR0 | ||
508 | /* Now the same for Free Buffer Ring 0 */ | ||
509 | if (rx_ring->pFbr0RingVa) { | ||
510 | /* First the packet memory */ | ||
511 | for (index = 0; index < | ||
512 | (rx_ring->Fbr0NumEntries / FBR_CHUNKS); index++) { | ||
513 | if (rx_ring->Fbr0MemVa[index]) { | ||
514 | bufsize = | ||
515 | (rx_ring->Fbr0BufferSize * | ||
516 | (FBR_CHUNKS + 1)) - 1; | ||
517 | |||
518 | pci_free_consistent(adapter->pdev, | ||
519 | bufsize, | ||
520 | rx_ring->Fbr0MemVa[index], | ||
521 | rx_ring->Fbr0MemPa[index]); | ||
522 | |||
523 | rx_ring->Fbr0MemVa[index] = NULL; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | /* Now the FIFO itself */ | ||
528 | rx_ring->pFbr0RingVa = (void *)((uint8_t *) rx_ring->pFbr0RingVa - | ||
529 | rx_ring->Fbr0offset); | ||
530 | |||
531 | bufsize = | ||
532 | (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff; | ||
533 | |||
534 | pci_free_consistent(adapter->pdev, | ||
535 | bufsize, | ||
536 | rx_ring->pFbr0RingVa, rx_ring->pFbr0RingPa); | ||
537 | |||
538 | rx_ring->pFbr0RingVa = NULL; | ||
539 | } | ||
540 | #endif | ||
541 | |||
542 | /* Free Packet Status Ring */ | ||
543 | if (rx_ring->pPSRingVa) { | ||
544 | rx_ring->pPSRingVa = (void *)((uint8_t *) rx_ring->pPSRingVa - | ||
545 | rx_ring->pPSRingOffset); | ||
546 | |||
547 | pktStatRingSize = | ||
548 | sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries; | ||
549 | |||
550 | pci_free_consistent(adapter->pdev, | ||
551 | pktStatRingSize + 0x0fff, | ||
552 | rx_ring->pPSRingVa, rx_ring->pPSRingPa); | ||
553 | |||
554 | rx_ring->pPSRingVa = NULL; | ||
555 | } | ||
556 | |||
557 | /* Free area of memory for the writeback of status information */ | ||
558 | if (rx_ring->pRxStatusVa) { | ||
559 | rx_ring->pRxStatusVa = (void *)((uint8_t *) rx_ring->pRxStatusVa - | ||
560 | rx_ring->RxStatusOffset); | ||
561 | |||
562 | pci_free_consistent(adapter->pdev, | ||
563 | sizeof(RX_STATUS_BLOCK_t) + 0x7, | ||
564 | rx_ring->pRxStatusVa, rx_ring->pRxStatusPa); | ||
565 | |||
566 | rx_ring->pRxStatusVa = NULL; | ||
567 | } | ||
568 | |||
569 | /* Free receive buffer pool */ | ||
570 | |||
571 | /* Free receive packet pool */ | ||
572 | |||
573 | /* Destroy the lookaside (RFD) pool */ | ||
574 | if (MP_TEST_FLAG(adapter, fMP_ADAPTER_RECV_LOOKASIDE)) { | ||
575 | kmem_cache_destroy(rx_ring->RecvLookaside); | ||
576 | MP_CLEAR_FLAG(adapter, fMP_ADAPTER_RECV_LOOKASIDE); | ||
577 | } | ||
578 | |||
579 | /* Free the FBR Lookup Table */ | ||
580 | #ifdef USE_FBR0 | ||
581 | kfree(rx_ring->Fbr[0]); | ||
582 | #endif | ||
583 | |||
584 | kfree(rx_ring->Fbr[1]); | ||
585 | |||
586 | /* Reset Counters */ | ||
587 | rx_ring->nReadyRecv = 0; | ||
588 | |||
589 | DBG_LEAVE(et131x_dbginfo); | ||
590 | } | ||
591 | |||
592 | /** | ||
593 | * et131x_init_recv - Initialize receive data structures. | ||
594 | * @adapter: pointer to our private adapter structure | ||
595 | * | ||
596 | * Returns 0 on success and errno on failure (as defined in errno.h) | ||
597 | */ | ||
598 | int et131x_init_recv(struct et131x_adapter *adapter) | ||
599 | { | ||
600 | int status = -ENOMEM; | ||
601 | PMP_RFD pMpRfd = NULL; | ||
602 | uint32_t RfdCount; | ||
603 | uint32_t TotalNumRfd = 0; | ||
604 | RX_RING_t *rx_ring = NULL; | ||
605 | |||
606 | DBG_ENTER(et131x_dbginfo); | ||
607 | |||
608 | /* Setup some convenience pointers */ | ||
609 | rx_ring = (RX_RING_t *) & adapter->RxRing; | ||
610 | |||
611 | /* Setup each RFD */ | ||
612 | for (RfdCount = 0; RfdCount < rx_ring->NumRfd; RfdCount++) { | ||
613 | pMpRfd = (MP_RFD *) kmem_cache_alloc(rx_ring->RecvLookaside, | ||
614 | GFP_ATOMIC | GFP_DMA); | ||
615 | |||
616 | if (!pMpRfd) { | ||
617 | DBG_ERROR(et131x_dbginfo, | ||
618 | "Couldn't alloc RFD out of kmem_cache\n"); | ||
619 | status = -ENOMEM; | ||
620 | continue; | ||
621 | } | ||
622 | |||
623 | status = et131x_rfd_resources_alloc(adapter, pMpRfd); | ||
624 | if (status != 0) { | ||
625 | DBG_ERROR(et131x_dbginfo, | ||
626 | "Couldn't alloc packet for RFD\n"); | ||
627 | kmem_cache_free(rx_ring->RecvLookaside, pMpRfd); | ||
628 | continue; | ||
629 | } | ||
630 | |||
631 | /* Add this RFD to the RecvList */ | ||
632 | list_add_tail(&pMpRfd->list_node, &rx_ring->RecvList); | ||
633 | |||
634 | /* Increment both the available RFD's, and the total RFD's. */ | ||
635 | rx_ring->nReadyRecv++; | ||
636 | TotalNumRfd++; | ||
637 | } | ||
638 | |||
639 | if (TotalNumRfd > NIC_MIN_NUM_RFD) { | ||
640 | status = 0; | ||
641 | } | ||
642 | |||
643 | rx_ring->NumRfd = TotalNumRfd; | ||
644 | |||
645 | if (status != 0) { | ||
646 | kmem_cache_free(rx_ring->RecvLookaside, pMpRfd); | ||
647 | DBG_ERROR(et131x_dbginfo, | ||
648 | "Allocation problems in et131x_init_recv\n"); | ||
649 | } | ||
650 | |||
651 | DBG_LEAVE(et131x_dbginfo); | ||
652 | return status; | ||
653 | } | ||
654 | |||
655 | /** | ||
656 | * et131x_rfd_resources_alloc | ||
657 | * @adapter: pointer to our private adapter structure | ||
658 | * @pMpRfd: pointer to a RFD | ||
659 | * | ||
660 | * Returns 0 on success and errno on failure (as defined in errno.h) | ||
661 | */ | ||
662 | int et131x_rfd_resources_alloc(struct et131x_adapter *adapter, MP_RFD *pMpRfd) | ||
663 | { | ||
664 | pMpRfd->Packet = NULL; | ||
665 | |||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | /** | ||
670 | * et131x_rfd_resources_free - Free the packet allocated for the given RFD | ||
671 | * @adapter: pointer to our private adapter structure | ||
672 | * @pMpRfd: pointer to a RFD | ||
673 | */ | ||
674 | void et131x_rfd_resources_free(struct et131x_adapter *adapter, MP_RFD *pMpRfd) | ||
675 | { | ||
676 | pMpRfd->Packet = NULL; | ||
677 | kmem_cache_free(adapter->RxRing.RecvLookaside, pMpRfd); | ||
678 | } | ||
679 | |||
680 | /** | ||
681 | * ConfigRxDmaRegs - Start of Rx_DMA init sequence | ||
682 | * @pAdapter: pointer to our adapter structure | ||
683 | */ | ||
684 | void ConfigRxDmaRegs(struct et131x_adapter *pAdapter) | ||
685 | { | ||
686 | struct _RXDMA_t __iomem *pRxDma = &pAdapter->CSRAddress->rxdma; | ||
687 | struct _rx_ring_t *pRxLocal = &pAdapter->RxRing; | ||
688 | PFBR_DESC_t pFbrEntry; | ||
689 | uint32_t iEntry; | ||
690 | RXDMA_PSR_NUM_DES_t psr_num_des; | ||
691 | unsigned long lockflags; | ||
692 | |||
693 | DBG_ENTER(et131x_dbginfo); | ||
694 | |||
695 | /* Halt RXDMA to perform the reconfigure. */ | ||
696 | et131x_rx_dma_disable(pAdapter); | ||
697 | |||
698 | /* Load the completion writeback physical address | ||
699 | * | ||
700 | * NOTE : pci_alloc_consistent(), used above to alloc DMA regions, | ||
701 | * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses | ||
702 | * are ever returned, make sure the high part is retrieved here | ||
703 | * before storing the adjusted address. | ||
704 | */ | ||
705 | writel((uint32_t) (pRxLocal->RxStatusRealPA >> 32), | ||
706 | &pRxDma->dma_wb_base_hi); | ||
707 | writel((uint32_t) pRxLocal->RxStatusRealPA, &pRxDma->dma_wb_base_lo); | ||
708 | |||
709 | memset(pRxLocal->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t)); | ||
710 | |||
711 | /* Set the address and parameters of the packet status ring into the | ||
712 | * 1310's registers | ||
713 | */ | ||
714 | writel((uint32_t) (pRxLocal->pPSRingRealPa >> 32), | ||
715 | &pRxDma->psr_base_hi); | ||
716 | writel((uint32_t) pRxLocal->pPSRingRealPa, &pRxDma->psr_base_lo); | ||
717 | writel(pRxLocal->PsrNumEntries - 1, &pRxDma->psr_num_des.value); | ||
718 | writel(0, &pRxDma->psr_full_offset.value); | ||
719 | |||
720 | psr_num_des.value = readl(&pRxDma->psr_num_des.value); | ||
721 | writel((psr_num_des.bits.psr_ndes * LO_MARK_PERCENT_FOR_PSR) / 100, | ||
722 | &pRxDma->psr_min_des.value); | ||
723 | |||
724 | spin_lock_irqsave(&pAdapter->RcvLock, lockflags); | ||
725 | |||
726 | /* These local variables track the PSR in the adapter structure */ | ||
727 | pRxLocal->local_psr_full.bits.psr_full = 0; | ||
728 | pRxLocal->local_psr_full.bits.psr_full_wrap = 0; | ||
729 | |||
730 | /* Now's the best time to initialize FBR1 contents */ | ||
731 | pFbrEntry = (PFBR_DESC_t) pRxLocal->pFbr1RingVa; | ||
732 | for (iEntry = 0; iEntry < pRxLocal->Fbr1NumEntries; iEntry++) { | ||
733 | pFbrEntry->addr_hi = pRxLocal->Fbr[1]->PAHigh[iEntry]; | ||
734 | pFbrEntry->addr_lo = pRxLocal->Fbr[1]->PALow[iEntry]; | ||
735 | pFbrEntry->word2.bits.bi = iEntry; | ||
736 | pFbrEntry++; | ||
737 | } | ||
738 | |||
739 | /* Set the address and parameters of Free buffer ring 1 (and 0 if | ||
740 | * required) into the 1310's registers | ||
741 | */ | ||
742 | writel((uint32_t) (pRxLocal->Fbr1Realpa >> 32), &pRxDma->fbr1_base_hi); | ||
743 | writel((uint32_t) pRxLocal->Fbr1Realpa, &pRxDma->fbr1_base_lo); | ||
744 | writel(pRxLocal->Fbr1NumEntries - 1, &pRxDma->fbr1_num_des.value); | ||
745 | |||
746 | { | ||
747 | DMA10W_t fbr1_full = { 0 }; | ||
748 | |||
749 | fbr1_full.bits.val = 0; | ||
750 | fbr1_full.bits.wrap = 1; | ||
751 | writel(fbr1_full.value, &pRxDma->fbr1_full_offset.value); | ||
752 | } | ||
753 | |||
754 | /* This variable tracks the free buffer ring 1 full position, so it | ||
755 | * has to match the above. | ||
756 | */ | ||
757 | pRxLocal->local_Fbr1_full.bits.val = 0; | ||
758 | pRxLocal->local_Fbr1_full.bits.wrap = 1; | ||
759 | writel(((pRxLocal->Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, | ||
760 | &pRxDma->fbr1_min_des.value); | ||
761 | |||
762 | #ifdef USE_FBR0 | ||
763 | /* Now's the best time to initialize FBR0 contents */ | ||
764 | pFbrEntry = (PFBR_DESC_t) pRxLocal->pFbr0RingVa; | ||
765 | for (iEntry = 0; iEntry < pRxLocal->Fbr0NumEntries; iEntry++) { | ||
766 | pFbrEntry->addr_hi = pRxLocal->Fbr[0]->PAHigh[iEntry]; | ||
767 | pFbrEntry->addr_lo = pRxLocal->Fbr[0]->PALow[iEntry]; | ||
768 | pFbrEntry->word2.bits.bi = iEntry; | ||
769 | pFbrEntry++; | ||
770 | } | ||
771 | |||
772 | writel((uint32_t) (pRxLocal->Fbr0Realpa >> 32), &pRxDma->fbr0_base_hi); | ||
773 | writel((uint32_t) pRxLocal->Fbr0Realpa, &pRxDma->fbr0_base_lo); | ||
774 | writel(pRxLocal->Fbr0NumEntries - 1, &pRxDma->fbr0_num_des.value); | ||
775 | |||
776 | { | ||
777 | DMA10W_t fbr0_full = { 0 }; | ||
778 | |||
779 | fbr0_full.bits.val = 0; | ||
780 | fbr0_full.bits.wrap = 1; | ||
781 | writel(fbr0_full.value, &pRxDma->fbr0_full_offset.value); | ||
782 | } | ||
783 | |||
784 | /* This variable tracks the free buffer ring 0 full position, so it | ||
785 | * has to match the above. | ||
786 | */ | ||
787 | pRxLocal->local_Fbr0_full.bits.val = 0; | ||
788 | pRxLocal->local_Fbr0_full.bits.wrap = 1; | ||
789 | writel(((pRxLocal->Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, | ||
790 | &pRxDma->fbr0_min_des.value); | ||
791 | #endif | ||
792 | |||
793 | /* Program the number of packets we will receive before generating an | ||
794 | * interrupt. | ||
795 | * For version B silicon, this value gets updated once autoneg is | ||
796 | *complete. | ||
797 | */ | ||
798 | writel(pAdapter->RegistryRxNumBuffers, &pRxDma->num_pkt_done.value); | ||
799 | |||
800 | /* The "time_done" is not working correctly to coalesce interrupts | ||
801 | * after a given time period, but rather is giving us an interrupt | ||
802 | * regardless of whether we have received packets. | ||
803 | * This value gets updated once autoneg is complete. | ||
804 | */ | ||
805 | writel(pAdapter->RegistryRxTimeInterval, &pRxDma->max_pkt_time.value); | ||
806 | |||
807 | spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags); | ||
808 | |||
809 | DBG_LEAVE(et131x_dbginfo); | ||
810 | } | ||
811 | |||
812 | /** | ||
813 | * SetRxDmaTimer - Set the heartbeat timer according to line rate. | ||
814 | * @pAdapter: pointer to our adapter structure | ||
815 | */ | ||
816 | void SetRxDmaTimer(struct et131x_adapter *pAdapter) | ||
817 | { | ||
818 | /* For version B silicon, we do not use the RxDMA timer for 10 and 100 | ||
819 | * Mbits/s line rates. We do not enable and RxDMA interrupt coalescing. | ||
820 | */ | ||
821 | if ((pAdapter->uiLinkSpeed == TRUEPHY_SPEED_100MBPS) || | ||
822 | (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS)) { | ||
823 | writel(0, &pAdapter->CSRAddress->rxdma.max_pkt_time.value); | ||
824 | writel(1, &pAdapter->CSRAddress->rxdma.num_pkt_done.value); | ||
825 | } | ||
826 | } | ||
827 | |||
828 | /** | ||
829 | * et131x_rx_dma_disable - Stop of Rx_DMA on the ET1310 | ||
830 | * @pAdapter: pointer to our adapter structure | ||
831 | */ | ||
832 | void et131x_rx_dma_disable(struct et131x_adapter *pAdapter) | ||
833 | { | ||
834 | RXDMA_CSR_t csr; | ||
835 | |||
836 | DBG_ENTER(et131x_dbginfo); | ||
837 | |||
838 | /* Setup the receive dma configuration register */ | ||
839 | writel(0x00002001, &pAdapter->CSRAddress->rxdma.csr.value); | ||
840 | csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value); | ||
841 | if (csr.bits.halt_status != 1) { | ||
842 | udelay(5); | ||
843 | csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value); | ||
844 | if (csr.bits.halt_status != 1) { | ||
845 | DBG_ERROR(et131x_dbginfo, | ||
846 | "RX Dma failed to enter halt state. CSR 0x%08x\n", | ||
847 | csr.value); | ||
848 | } | ||
849 | } | ||
850 | |||
851 | DBG_LEAVE(et131x_dbginfo); | ||
852 | } | ||
853 | |||
854 | /** | ||
855 | * et131x_rx_dma_enable - re-start of Rx_DMA on the ET1310. | ||
856 | * @pAdapter: pointer to our adapter structure | ||
857 | */ | ||
858 | void et131x_rx_dma_enable(struct et131x_adapter *pAdapter) | ||
859 | { | ||
860 | DBG_RX_ENTER(et131x_dbginfo); | ||
861 | |||
862 | if (pAdapter->RegistryPhyLoopbk) { | ||
863 | /* RxDMA is disabled for loopback operation. */ | ||
864 | writel(0x1, &pAdapter->CSRAddress->rxdma.csr.value); | ||
865 | } else { | ||
866 | /* Setup the receive dma configuration register for normal operation */ | ||
867 | RXDMA_CSR_t csr = { 0 }; | ||
868 | |||
869 | csr.bits.fbr1_enable = 1; | ||
870 | if (pAdapter->RxRing.Fbr1BufferSize == 4096) { | ||
871 | csr.bits.fbr1_size = 1; | ||
872 | } else if (pAdapter->RxRing.Fbr1BufferSize == 8192) { | ||
873 | csr.bits.fbr1_size = 2; | ||
874 | } else if (pAdapter->RxRing.Fbr1BufferSize == 16384) { | ||
875 | csr.bits.fbr1_size = 3; | ||
876 | } | ||
877 | #ifdef USE_FBR0 | ||
878 | csr.bits.fbr0_enable = 1; | ||
879 | if (pAdapter->RxRing.Fbr0BufferSize == 256) { | ||
880 | csr.bits.fbr0_size = 1; | ||
881 | } else if (pAdapter->RxRing.Fbr0BufferSize == 512) { | ||
882 | csr.bits.fbr0_size = 2; | ||
883 | } else if (pAdapter->RxRing.Fbr0BufferSize == 1024) { | ||
884 | csr.bits.fbr0_size = 3; | ||
885 | } | ||
886 | #endif | ||
887 | writel(csr.value, &pAdapter->CSRAddress->rxdma.csr.value); | ||
888 | |||
889 | csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value); | ||
890 | if (csr.bits.halt_status != 0) { | ||
891 | udelay(5); | ||
892 | csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value); | ||
893 | if (csr.bits.halt_status != 0) { | ||
894 | DBG_ERROR(et131x_dbginfo, | ||
895 | "RX Dma failed to exit halt state. CSR 0x%08x\n", | ||
896 | csr.value); | ||
897 | } | ||
898 | } | ||
899 | } | ||
900 | |||
901 | DBG_RX_LEAVE(et131x_dbginfo); | ||
902 | } | ||
903 | |||
904 | /** | ||
905 | * nic_rx_pkts - Checks the hardware for available packets | ||
906 | * @pAdapter: pointer to our adapter | ||
907 | * | ||
908 | * Returns pMpRfd, a pointer to our MPRFD. | ||
909 | * | ||
910 | * Checks the hardware for available packets, using completion ring | ||
911 | * If packets are available, it gets an RFD from the RecvList, attaches | ||
912 | * the packet to it, puts the RFD in the RecvPendList, and also returns | ||
913 | * the pointer to the RFD. | ||
914 | */ | ||
915 | PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter) | ||
916 | { | ||
917 | struct _rx_ring_t *pRxLocal = &pAdapter->RxRing; | ||
918 | PRX_STATUS_BLOCK_t pRxStatusBlock; | ||
919 | PPKT_STAT_DESC_t pPSREntry; | ||
920 | PMP_RFD pMpRfd; | ||
921 | uint32_t nIndex; | ||
922 | uint8_t *pBufVa; | ||
923 | unsigned long lockflags; | ||
924 | struct list_head *element; | ||
925 | uint8_t ringIndex; | ||
926 | uint16_t bufferIndex; | ||
927 | uint32_t localLen; | ||
928 | PKT_STAT_DESC_WORD0_t Word0; | ||
929 | |||
930 | |||
931 | DBG_RX_ENTER(et131x_dbginfo); | ||
932 | |||
933 | /* RX Status block is written by the DMA engine prior to every | ||
934 | * interrupt. It contains the next to be used entry in the Packet | ||
935 | * Status Ring, and also the two Free Buffer rings. | ||
936 | */ | ||
937 | pRxStatusBlock = (PRX_STATUS_BLOCK_t) pRxLocal->pRxStatusVa; | ||
938 | |||
939 | if (pRxStatusBlock->Word1.bits.PSRoffset == | ||
940 | pRxLocal->local_psr_full.bits.psr_full && | ||
941 | pRxStatusBlock->Word1.bits.PSRwrap == | ||
942 | pRxLocal->local_psr_full.bits.psr_full_wrap) { | ||
943 | /* Looks like this ring is not updated yet */ | ||
944 | DBG_RX(et131x_dbginfo, "(0)\n"); | ||
945 | DBG_RX_LEAVE(et131x_dbginfo); | ||
946 | return NULL; | ||
947 | } | ||
948 | |||
949 | /* The packet status ring indicates that data is available. */ | ||
950 | pPSREntry = (PPKT_STAT_DESC_t) (pRxLocal->pPSRingVa) + | ||
951 | pRxLocal->local_psr_full.bits.psr_full; | ||
952 | |||
953 | /* Grab any information that is required once the PSR is | ||
954 | * advanced, since we can no longer rely on the memory being | ||
955 | * accurate | ||
956 | */ | ||
957 | localLen = pPSREntry->word1.bits.length; | ||
958 | ringIndex = (uint8_t) pPSREntry->word1.bits.ri; | ||
959 | bufferIndex = (uint16_t) pPSREntry->word1.bits.bi; | ||
960 | Word0 = pPSREntry->word0; | ||
961 | |||
962 | DBG_RX(et131x_dbginfo, "RX PACKET STATUS\n"); | ||
963 | DBG_RX(et131x_dbginfo, "\tlength : %d\n", localLen); | ||
964 | DBG_RX(et131x_dbginfo, "\tringIndex : %d\n", ringIndex); | ||
965 | DBG_RX(et131x_dbginfo, "\tbufferIndex : %d\n", bufferIndex); | ||
966 | DBG_RX(et131x_dbginfo, "\tword0 : 0x%08x\n", Word0.value); | ||
967 | |||
968 | #if 0 | ||
969 | /* Check the Status Word that the MAC has appended to the PSR | ||
970 | * entry in case the MAC has detected errors. | ||
971 | */ | ||
972 | if (Word0.value & ALCATEL_BAD_STATUS) { | ||
973 | DBG_ERROR(et131x_dbginfo, | ||
974 | "NICRxPkts >> Alcatel Status Word error." | ||
975 | "Value 0x%08x\n", pPSREntry->word0.value); | ||
976 | } | ||
977 | #endif | ||
978 | |||
979 | /* Indicate that we have used this PSR entry. */ | ||
980 | if (++pRxLocal->local_psr_full.bits.psr_full > | ||
981 | pRxLocal->PsrNumEntries - 1) { | ||
982 | pRxLocal->local_psr_full.bits.psr_full = 0; | ||
983 | pRxLocal->local_psr_full.bits.psr_full_wrap ^= 1; | ||
984 | } | ||
985 | |||
986 | writel(pRxLocal->local_psr_full.value, | ||
987 | &pAdapter->CSRAddress->rxdma.psr_full_offset.value); | ||
988 | |||
989 | #ifndef USE_FBR0 | ||
990 | if (ringIndex != 1) { | ||
991 | DBG_ERROR(et131x_dbginfo, | ||
992 | "NICRxPkts PSR Entry %d indicates " | ||
993 | "Buffer Ring 0 in use\n", | ||
994 | pRxLocal->local_psr_full.bits.psr_full); | ||
995 | DBG_RX_LEAVE(et131x_dbginfo); | ||
996 | return NULL; | ||
997 | } | ||
998 | #endif | ||
999 | |||
1000 | #ifdef USE_FBR0 | ||
1001 | if (ringIndex > 1 || | ||
1002 | (ringIndex == 0 && | ||
1003 | bufferIndex > pRxLocal->Fbr0NumEntries - 1) || | ||
1004 | (ringIndex == 1 && | ||
1005 | bufferIndex > pRxLocal->Fbr1NumEntries - 1)) | ||
1006 | #else | ||
1007 | if (ringIndex != 1 || | ||
1008 | bufferIndex > pRxLocal->Fbr1NumEntries - 1) | ||
1009 | #endif | ||
1010 | { | ||
1011 | /* Illegal buffer or ring index cannot be used by S/W*/ | ||
1012 | DBG_ERROR(et131x_dbginfo, | ||
1013 | "NICRxPkts PSR Entry %d indicates " | ||
1014 | "length of %d and/or bad bi(%d)\n", | ||
1015 | pRxLocal->local_psr_full.bits.psr_full, | ||
1016 | localLen, bufferIndex); | ||
1017 | DBG_RX_LEAVE(et131x_dbginfo); | ||
1018 | return NULL; | ||
1019 | } | ||
1020 | |||
1021 | /* Get and fill the RFD. */ | ||
1022 | spin_lock_irqsave(&pAdapter->RcvLock, lockflags); | ||
1023 | |||
1024 | pMpRfd = NULL; | ||
1025 | element = pRxLocal->RecvList.next; | ||
1026 | pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node); | ||
1027 | |||
1028 | if (pMpRfd == NULL) { | ||
1029 | DBG_RX(et131x_dbginfo, | ||
1030 | "NULL RFD returned from RecvList via list_entry()\n"); | ||
1031 | DBG_RX_LEAVE(et131x_dbginfo); | ||
1032 | spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags); | ||
1033 | return NULL; | ||
1034 | } | ||
1035 | |||
1036 | list_del(&pMpRfd->list_node); | ||
1037 | pRxLocal->nReadyRecv--; | ||
1038 | |||
1039 | spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags); | ||
1040 | |||
1041 | pMpRfd->iBufferIndex = bufferIndex; | ||
1042 | pMpRfd->iRingIndex = ringIndex; | ||
1043 | |||
1044 | /* In V1 silicon, there is a bug which screws up filtering of | ||
1045 | * runt packets. Therefore runt packet filtering is disabled | ||
1046 | * in the MAC and the packets are dropped here. They are | ||
1047 | * also counted here. | ||
1048 | */ | ||
1049 | if (localLen < (NIC_MIN_PACKET_SIZE + 4)) { | ||
1050 | pAdapter->Stats.other_errors++; | ||
1051 | localLen = 0; | ||
1052 | } | ||
1053 | |||
1054 | if (localLen) { | ||
1055 | if (pAdapter->ReplicaPhyLoopbk == 1) { | ||
1056 | pBufVa = pRxLocal->Fbr[ringIndex]->Va[bufferIndex]; | ||
1057 | |||
1058 | if (memcmp(&pBufVa[6], &pAdapter->CurrentAddress[0], | ||
1059 | ETH_ALEN) == 0) { | ||
1060 | if (memcmp(&pBufVa[42], "Replica packet", | ||
1061 | ETH_HLEN)) { | ||
1062 | pAdapter->ReplicaPhyLoopbkPF = 1; | ||
1063 | } | ||
1064 | } | ||
1065 | DBG_WARNING(et131x_dbginfo, | ||
1066 | "pBufVa:\t%02x:%02x:%02x:%02x:%02x:%02x\n", | ||
1067 | pBufVa[6], pBufVa[7], pBufVa[8], | ||
1068 | pBufVa[9], pBufVa[10], pBufVa[11]); | ||
1069 | |||
1070 | DBG_WARNING(et131x_dbginfo, | ||
1071 | "CurrentAddr:\t%02x:%02x:%02x:%02x:%02x:%02x\n", | ||
1072 | pAdapter->CurrentAddress[0], | ||
1073 | pAdapter->CurrentAddress[1], | ||
1074 | pAdapter->CurrentAddress[2], | ||
1075 | pAdapter->CurrentAddress[3], | ||
1076 | pAdapter->CurrentAddress[4], | ||
1077 | pAdapter->CurrentAddress[5]); | ||
1078 | } | ||
1079 | |||
1080 | /* Determine if this is a multicast packet coming in */ | ||
1081 | if ((Word0.value & ALCATEL_MULTICAST_PKT) && | ||
1082 | !(Word0.value & ALCATEL_BROADCAST_PKT)) { | ||
1083 | /* Promiscuous mode and Multicast mode are | ||
1084 | * not mutually exclusive as was first | ||
1085 | * thought. I guess Promiscuous is just | ||
1086 | * considered a super-set of the other | ||
1087 | * filters. Generally filter is 0x2b when in | ||
1088 | * promiscuous mode. | ||
1089 | */ | ||
1090 | if ((pAdapter->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) | ||
1091 | && !(pAdapter->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS) | ||
1092 | && !(pAdapter->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { | ||
1093 | pBufVa = pRxLocal->Fbr[ringIndex]-> | ||
1094 | Va[bufferIndex]; | ||
1095 | |||
1096 | /* Loop through our list to see if the | ||
1097 | * destination address of this packet | ||
1098 | * matches one in our list. | ||
1099 | */ | ||
1100 | for (nIndex = 0; | ||
1101 | nIndex < pAdapter->MCAddressCount; | ||
1102 | nIndex++) { | ||
1103 | if (pBufVa[0] == | ||
1104 | pAdapter->MCList[nIndex][0] | ||
1105 | && pBufVa[1] == | ||
1106 | pAdapter->MCList[nIndex][1] | ||
1107 | && pBufVa[2] == | ||
1108 | pAdapter->MCList[nIndex][2] | ||
1109 | && pBufVa[3] == | ||
1110 | pAdapter->MCList[nIndex][3] | ||
1111 | && pBufVa[4] == | ||
1112 | pAdapter->MCList[nIndex][4] | ||
1113 | && pBufVa[5] == | ||
1114 | pAdapter->MCList[nIndex][5]) { | ||
1115 | break; | ||
1116 | } | ||
1117 | } | ||
1118 | |||
1119 | /* If our index is equal to the number | ||
1120 | * of Multicast address we have, then | ||
1121 | * this means we did not find this | ||
1122 | * packet's matching address in our | ||
1123 | * list. Set the PacketSize to zero, | ||
1124 | * so we free our RFD when we return | ||
1125 | * from this function. | ||
1126 | */ | ||
1127 | if (nIndex == pAdapter->MCAddressCount) { | ||
1128 | localLen = 0; | ||
1129 | } | ||
1130 | } | ||
1131 | |||
1132 | if (localLen > 0) { | ||
1133 | pAdapter->Stats.multircv++; | ||
1134 | } | ||
1135 | } else if (Word0.value & ALCATEL_BROADCAST_PKT) { | ||
1136 | pAdapter->Stats.brdcstrcv++; | ||
1137 | } else { | ||
1138 | /* Not sure what this counter measures in | ||
1139 | * promiscuous mode. Perhaps we should check | ||
1140 | * the MAC address to see if it is directed | ||
1141 | * to us in promiscuous mode. | ||
1142 | */ | ||
1143 | pAdapter->Stats.unircv++; | ||
1144 | } | ||
1145 | } | ||
1146 | |||
1147 | if (localLen > 0) { | ||
1148 | struct sk_buff *skb = NULL; | ||
1149 | |||
1150 | //pMpRfd->PacketSize = localLen - 4; | ||
1151 | pMpRfd->PacketSize = localLen; | ||
1152 | |||
1153 | skb = dev_alloc_skb(pMpRfd->PacketSize + 2); | ||
1154 | if (!skb) { | ||
1155 | DBG_ERROR(et131x_dbginfo, | ||
1156 | "Couldn't alloc an SKB for Rx\n"); | ||
1157 | DBG_RX_LEAVE(et131x_dbginfo); | ||
1158 | return NULL; | ||
1159 | } | ||
1160 | |||
1161 | pAdapter->net_stats.rx_bytes += pMpRfd->PacketSize; | ||
1162 | |||
1163 | memcpy(skb_put(skb, pMpRfd->PacketSize), | ||
1164 | pRxLocal->Fbr[ringIndex]->Va[bufferIndex], | ||
1165 | pMpRfd->PacketSize); | ||
1166 | |||
1167 | skb->dev = pAdapter->netdev; | ||
1168 | skb->protocol = eth_type_trans(skb, pAdapter->netdev); | ||
1169 | skb->ip_summed = CHECKSUM_NONE; | ||
1170 | |||
1171 | netif_rx(skb); | ||
1172 | } else { | ||
1173 | pMpRfd->PacketSize = 0; | ||
1174 | } | ||
1175 | |||
1176 | nic_return_rfd(pAdapter, pMpRfd); | ||
1177 | |||
1178 | DBG_RX(et131x_dbginfo, "(1)\n"); | ||
1179 | DBG_RX_LEAVE(et131x_dbginfo); | ||
1180 | return pMpRfd; | ||
1181 | } | ||
1182 | |||
1183 | /** | ||
1184 | * et131x_reset_recv - Reset the receive list | ||
1185 | * @pAdapter: pointer to our adapter | ||
1186 | * | ||
1187 | * Assumption, Rcv spinlock has been acquired. | ||
1188 | */ | ||
1189 | void et131x_reset_recv(struct et131x_adapter *pAdapter) | ||
1190 | { | ||
1191 | PMP_RFD pMpRfd; | ||
1192 | struct list_head *element; | ||
1193 | |||
1194 | DBG_ENTER(et131x_dbginfo); | ||
1195 | |||
1196 | DBG_ASSERT(!list_empty(&pAdapter->RxRing.RecvList)); | ||
1197 | |||
1198 | /* Take all the RFD's from the pending list, and stick them on the | ||
1199 | * RecvList. | ||
1200 | */ | ||
1201 | while (!list_empty(&pAdapter->RxRing.RecvPendingList)) { | ||
1202 | element = pAdapter->RxRing.RecvPendingList.next; | ||
1203 | |||
1204 | pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node); | ||
1205 | |||
1206 | list_del(&pMpRfd->list_node); | ||
1207 | list_add_tail(&pMpRfd->list_node, &pAdapter->RxRing.RecvList); | ||
1208 | } | ||
1209 | |||
1210 | DBG_LEAVE(et131x_dbginfo); | ||
1211 | } | ||
1212 | |||
1213 | /** | ||
1214 | * et131x_handle_recv_interrupt - Interrupt handler for receive processing | ||
1215 | * @pAdapter: pointer to our adapter | ||
1216 | * | ||
1217 | * Assumption, Rcv spinlock has been acquired. | ||
1218 | */ | ||
1219 | void et131x_handle_recv_interrupt(struct et131x_adapter *pAdapter) | ||
1220 | { | ||
1221 | PMP_RFD pMpRfd = NULL; | ||
1222 | struct sk_buff *PacketArray[NUM_PACKETS_HANDLED]; | ||
1223 | PMP_RFD RFDFreeArray[NUM_PACKETS_HANDLED]; | ||
1224 | uint32_t PacketArrayCount = 0; | ||
1225 | uint32_t PacketsToHandle; | ||
1226 | uint32_t PacketFreeCount = 0; | ||
1227 | bool TempUnfinishedRec = false; | ||
1228 | |||
1229 | DBG_RX_ENTER(et131x_dbginfo); | ||
1230 | |||
1231 | PacketsToHandle = NUM_PACKETS_HANDLED; | ||
1232 | |||
1233 | /* Process up to available RFD's */ | ||
1234 | while (PacketArrayCount < PacketsToHandle) { | ||
1235 | if (list_empty(&pAdapter->RxRing.RecvList)) { | ||
1236 | DBG_ASSERT(pAdapter->RxRing.nReadyRecv == 0); | ||
1237 | DBG_ERROR(et131x_dbginfo, "NO RFD's !!!!!!!!!!!!!\n"); | ||
1238 | TempUnfinishedRec = true; | ||
1239 | break; | ||
1240 | } | ||
1241 | |||
1242 | pMpRfd = nic_rx_pkts(pAdapter); | ||
1243 | |||
1244 | if (pMpRfd == NULL) { | ||
1245 | break; | ||
1246 | } | ||
1247 | |||
1248 | /* Do not receive any packets until a filter has been set. | ||
1249 | * Do not receive any packets until we are at D0. | ||
1250 | * Do not receive any packets until we have link. | ||
1251 | * If length is zero, return the RFD in order to advance the | ||
1252 | * Free buffer ring. | ||
1253 | */ | ||
1254 | if ((!pAdapter->PacketFilter) || | ||
1255 | (pAdapter->PoMgmt.PowerState != NdisDeviceStateD0) || | ||
1256 | (!MP_LINK_DETECTED(pAdapter)) || | ||
1257 | (pMpRfd->PacketSize == 0)) { | ||
1258 | continue; | ||
1259 | } | ||
1260 | |||
1261 | /* Increment the number of packets we received */ | ||
1262 | pAdapter->Stats.ipackets++; | ||
1263 | |||
1264 | /* Set the status on the packet, either resources or success */ | ||
1265 | if (pAdapter->RxRing.nReadyRecv >= RFD_LOW_WATER_MARK) { | ||
1266 | /* Put this RFD on the pending list | ||
1267 | * | ||
1268 | * NOTE: nic_rx_pkts() above is already returning the | ||
1269 | * RFD to the RecvList, so don't additionally do that | ||
1270 | * here. | ||
1271 | * Besides, we don't really need (at this point) the | ||
1272 | * pending list anyway. | ||
1273 | */ | ||
1274 | //spin_lock_irqsave( &pAdapter->RcvPendLock, lockflags ); | ||
1275 | //list_add_tail( &pMpRfd->list_node, &pAdapter->RxRing.RecvPendingList ); | ||
1276 | //spin_unlock_irqrestore( &pAdapter->RcvPendLock, lockflags ); | ||
1277 | |||
1278 | /* Update the number of outstanding Recvs */ | ||
1279 | //MP_INC_RCV_REF( pAdapter ); | ||
1280 | } else { | ||
1281 | RFDFreeArray[PacketFreeCount] = pMpRfd; | ||
1282 | PacketFreeCount++; | ||
1283 | |||
1284 | DBG_WARNING(et131x_dbginfo, | ||
1285 | "RFD's are running out !!!!!!!!!!!!!\n"); | ||
1286 | } | ||
1287 | |||
1288 | PacketArray[PacketArrayCount] = pMpRfd->Packet; | ||
1289 | PacketArrayCount++; | ||
1290 | } | ||
1291 | |||
1292 | if ((PacketArrayCount == NUM_PACKETS_HANDLED) || TempUnfinishedRec) { | ||
1293 | pAdapter->RxRing.UnfinishedReceives = true; | ||
1294 | writel(pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO, | ||
1295 | &pAdapter->CSRAddress->global.watchdog_timer); | ||
1296 | } else { | ||
1297 | /* Watchdog timer will disable itself if appropriate. */ | ||
1298 | pAdapter->RxRing.UnfinishedReceives = false; | ||
1299 | } | ||
1300 | |||
1301 | DBG_RX_LEAVE(et131x_dbginfo); | ||
1302 | } | ||
1303 | |||
1304 | /** | ||
1305 | * NICReturnRFD - Recycle a RFD and put it back onto the receive list | ||
1306 | * @pAdapter: pointer to our adapter | ||
1307 | * @pMpRfd: pointer to the RFD | ||
1308 | */ | ||
1309 | void nic_return_rfd(struct et131x_adapter *pAdapter, PMP_RFD pMpRfd) | ||
1310 | { | ||
1311 | struct _rx_ring_t *pRxLocal = &pAdapter->RxRing; | ||
1312 | struct _RXDMA_t __iomem *pRxDma = &pAdapter->CSRAddress->rxdma; | ||
1313 | uint16_t bi = pMpRfd->iBufferIndex; | ||
1314 | uint8_t ri = pMpRfd->iRingIndex; | ||
1315 | unsigned long lockflags; | ||
1316 | |||
1317 | DBG_RX_ENTER(et131x_dbginfo); | ||
1318 | |||
1319 | /* We don't use any of the OOB data besides status. Otherwise, we | ||
1320 | * need to clean up OOB data | ||
1321 | */ | ||
1322 | if ( | ||
1323 | #ifdef USE_FBR0 | ||
1324 | (ri == 0 && bi < pRxLocal->Fbr0NumEntries) || | ||
1325 | #endif | ||
1326 | (ri == 1 && bi < pRxLocal->Fbr1NumEntries)) { | ||
1327 | spin_lock_irqsave(&pAdapter->FbrLock, lockflags); | ||
1328 | |||
1329 | if (ri == 1) { | ||
1330 | PFBR_DESC_t pNextDesc = | ||
1331 | (PFBR_DESC_t) (pRxLocal->pFbr1RingVa) + | ||
1332 | pRxLocal->local_Fbr1_full.bits.val; | ||
1333 | |||
1334 | /* Handle the Free Buffer Ring advancement here. Write | ||
1335 | * the PA / Buffer Index for the returned buffer into | ||
1336 | * the oldest (next to be freed)FBR entry | ||
1337 | */ | ||
1338 | pNextDesc->addr_hi = pRxLocal->Fbr[1]->PAHigh[bi]; | ||
1339 | pNextDesc->addr_lo = pRxLocal->Fbr[1]->PALow[bi]; | ||
1340 | pNextDesc->word2.value = bi; | ||
1341 | |||
1342 | if (++pRxLocal->local_Fbr1_full.bits.val > | ||
1343 | (pRxLocal->Fbr1NumEntries - 1)) { | ||
1344 | pRxLocal->local_Fbr1_full.bits.val = 0; | ||
1345 | pRxLocal->local_Fbr1_full.bits.wrap ^= 1; | ||
1346 | } | ||
1347 | |||
1348 | writel(pRxLocal->local_Fbr1_full.value, | ||
1349 | &pRxDma->fbr1_full_offset.value); | ||
1350 | } | ||
1351 | #ifdef USE_FBR0 | ||
1352 | else { | ||
1353 | PFBR_DESC_t pNextDesc = | ||
1354 | (PFBR_DESC_t) pRxLocal->pFbr0RingVa + | ||
1355 | pRxLocal->local_Fbr0_full.bits.val; | ||
1356 | |||
1357 | /* Handle the Free Buffer Ring advancement here. Write | ||
1358 | * the PA / Buffer Index for the returned buffer into | ||
1359 | * the oldest (next to be freed) FBR entry | ||
1360 | */ | ||
1361 | pNextDesc->addr_hi = pRxLocal->Fbr[0]->PAHigh[bi]; | ||
1362 | pNextDesc->addr_lo = pRxLocal->Fbr[0]->PALow[bi]; | ||
1363 | pNextDesc->word2.value = bi; | ||
1364 | |||
1365 | if (++pRxLocal->local_Fbr0_full.bits.val > | ||
1366 | (pRxLocal->Fbr0NumEntries - 1)) { | ||
1367 | pRxLocal->local_Fbr0_full.bits.val = 0; | ||
1368 | pRxLocal->local_Fbr0_full.bits.wrap ^= 1; | ||
1369 | } | ||
1370 | |||
1371 | writel(pRxLocal->local_Fbr0_full.value, | ||
1372 | &pRxDma->fbr0_full_offset.value); | ||
1373 | } | ||
1374 | #endif | ||
1375 | spin_unlock_irqrestore(&pAdapter->FbrLock, lockflags); | ||
1376 | } else { | ||
1377 | DBG_ERROR(et131x_dbginfo, | ||
1378 | "NICReturnRFD illegal Buffer Index returned\n"); | ||
1379 | } | ||
1380 | |||
1381 | /* The processing on this RFD is done, so put it back on the tail of | ||
1382 | * our list | ||
1383 | */ | ||
1384 | spin_lock_irqsave(&pAdapter->RcvLock, lockflags); | ||
1385 | list_add_tail(&pMpRfd->list_node, &pRxLocal->RecvList); | ||
1386 | pRxLocal->nReadyRecv++; | ||
1387 | spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags); | ||
1388 | |||
1389 | DBG_ASSERT(pRxLocal->nReadyRecv <= pRxLocal->NumRfd); | ||
1390 | DBG_RX_LEAVE(et131x_dbginfo); | ||
1391 | } | ||
diff --git a/drivers/staging/et131x/et1310_rx.h b/drivers/staging/et131x/et1310_rx.h new file mode 100644 index 000000000000..ea66dbcd8dfc --- /dev/null +++ b/drivers/staging/et131x/et1310_rx.h | |||
@@ -0,0 +1,373 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_rx.h - Defines, structs, enums, prototypes, etc. pertaining to data | ||
12 | * reception. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef __ET1310_RX_H__ | ||
60 | #define __ET1310_RX_H__ | ||
61 | |||
62 | #include "et1310_address_map.h" | ||
63 | |||
64 | #define USE_FBR0 true | ||
65 | |||
66 | #ifdef USE_FBR0 | ||
67 | //#define FBR0_BUFFER_SIZE 256 | ||
68 | #endif | ||
69 | |||
70 | //#define FBR1_BUFFER_SIZE 2048 | ||
71 | |||
72 | #define FBR_CHUNKS 32 | ||
73 | |||
74 | #define MAX_DESC_PER_RING_RX 1024 | ||
75 | |||
76 | /* number of RFDs - default and min */ | ||
77 | #ifdef USE_FBR0 | ||
78 | #define RFD_LOW_WATER_MARK 40 | ||
79 | #define NIC_MIN_NUM_RFD 64 | ||
80 | #define NIC_DEFAULT_NUM_RFD 1024 | ||
81 | #else | ||
82 | #define RFD_LOW_WATER_MARK 20 | ||
83 | #define NIC_MIN_NUM_RFD 64 | ||
84 | #define NIC_DEFAULT_NUM_RFD 256 | ||
85 | #endif | ||
86 | |||
87 | #define NUM_PACKETS_HANDLED 256 | ||
88 | |||
89 | #define ALCATEL_BAD_STATUS 0xe47f0000 | ||
90 | #define ALCATEL_MULTICAST_PKT 0x01000000 | ||
91 | #define ALCATEL_BROADCAST_PKT 0x02000000 | ||
92 | |||
93 | /* typedefs for Free Buffer Descriptors */ | ||
94 | typedef union _FBR_WORD2_t { | ||
95 | u32 value; | ||
96 | struct { | ||
97 | #ifdef _BIT_FIELDS_HTOL | ||
98 | u32 reserved:22; // bits 10-31 | ||
99 | u32 bi:10; // bits 0-9(Buffer Index) | ||
100 | #else | ||
101 | u32 bi:10; // bits 0-9(Buffer Index) | ||
102 | u32 reserved:22; // bit 10-31 | ||
103 | #endif | ||
104 | } bits; | ||
105 | } FBR_WORD2_t, *PFBR_WORD2_t; | ||
106 | |||
107 | typedef struct _FBR_DESC_t { | ||
108 | u32 addr_lo; | ||
109 | u32 addr_hi; | ||
110 | FBR_WORD2_t word2; | ||
111 | } FBR_DESC_t, *PFBR_DESC_t; | ||
112 | |||
113 | /* Typedefs for Packet Status Ring Descriptors */ | ||
114 | typedef union _PKT_STAT_DESC_WORD0_t { | ||
115 | u32 value; | ||
116 | struct { | ||
117 | #ifdef _BIT_FIELDS_HTOL | ||
118 | // top 16 bits are from the Alcatel Status Word as enumerated in | ||
119 | // PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2) | ||
120 | #if 0 | ||
121 | u32 asw_trunc:1; // bit 31(Rx frame truncated) | ||
122 | #endif | ||
123 | u32 asw_long_evt:1; // bit 31(Rx long event) | ||
124 | u32 asw_VLAN_tag:1; // bit 30(VLAN tag detected) | ||
125 | u32 asw_unsupported_op:1; // bit 29(unsupported OP code) | ||
126 | u32 asw_pause_frame:1; // bit 28(is a pause frame) | ||
127 | u32 asw_control_frame:1; // bit 27(is a control frame) | ||
128 | u32 asw_dribble_nibble:1; // bit 26(spurious bits after EOP) | ||
129 | u32 asw_broadcast:1; // bit 25(has a broadcast address) | ||
130 | u32 asw_multicast:1; // bit 24(has a multicast address) | ||
131 | u32 asw_OK:1; // bit 23(valid CRC + no code error) | ||
132 | u32 asw_too_long:1; // bit 22(frame length > 1518 bytes) | ||
133 | u32 asw_len_chk_err:1; // bit 21(frame length field incorrect) | ||
134 | u32 asw_CRC_err:1; // bit 20(CRC error) | ||
135 | u32 asw_code_err:1; // bit 19(one or more nibbles signalled as errors) | ||
136 | u32 asw_false_carrier_event:1; // bit 18(bad carrier since last good packet) | ||
137 | u32 asw_RX_DV_event:1; // bit 17(short receive event detected) | ||
138 | u32 asw_prev_pkt_dropped:1;// bit 16(e.g. IFG too small on previous) | ||
139 | u32 unused:5; // bits 11-15 | ||
140 | u32 vp:1; // bit 10(VLAN Packet) | ||
141 | u32 jp:1; // bit 9(Jumbo Packet) | ||
142 | u32 ft:1; // bit 8(Frame Truncated) | ||
143 | u32 drop:1; // bit 7(Drop packet) | ||
144 | u32 rxmac_error:1; // bit 6(RXMAC Error Indicator) | ||
145 | u32 wol:1; // bit 5(WOL Event) | ||
146 | u32 tcpp:1; // bit 4(TCP checksum pass) | ||
147 | u32 tcpa:1; // bit 3(TCP checksum assist) | ||
148 | u32 ipp:1; // bit 2(IP checksum pass) | ||
149 | u32 ipa:1; // bit 1(IP checksum assist) | ||
150 | u32 hp:1; // bit 0(hash pass) | ||
151 | #else | ||
152 | u32 hp:1; // bit 0(hash pass) | ||
153 | u32 ipa:1; // bit 1(IP checksum assist) | ||
154 | u32 ipp:1; // bit 2(IP checksum pass) | ||
155 | u32 tcpa:1; // bit 3(TCP checksum assist) | ||
156 | u32 tcpp:1; // bit 4(TCP checksum pass) | ||
157 | u32 wol:1; // bit 5(WOL Event) | ||
158 | u32 rxmac_error:1; // bit 6(RXMAC Error Indicator) | ||
159 | u32 drop:1; // bit 7(Drop packet) | ||
160 | u32 ft:1; // bit 8(Frame Truncated) | ||
161 | u32 jp:1; // bit 9(Jumbo Packet) | ||
162 | u32 vp:1; // bit 10(VLAN Packet) | ||
163 | u32 unused:5; // bits 11-15 | ||
164 | u32 asw_prev_pkt_dropped:1;// bit 16(e.g. IFG too small on previous) | ||
165 | u32 asw_RX_DV_event:1; // bit 17(short receive event detected) | ||
166 | u32 asw_false_carrier_event:1; // bit 18(bad carrier since last good packet) | ||
167 | u32 asw_code_err:1; // bit 19(one or more nibbles signalled as errors) | ||
168 | u32 asw_CRC_err:1; // bit 20(CRC error) | ||
169 | u32 asw_len_chk_err:1; // bit 21(frame length field incorrect) | ||
170 | u32 asw_too_long:1; // bit 22(frame length > 1518 bytes) | ||
171 | u32 asw_OK:1; // bit 23(valid CRC + no code error) | ||
172 | u32 asw_multicast:1; // bit 24(has a multicast address) | ||
173 | u32 asw_broadcast:1; // bit 25(has a broadcast address) | ||
174 | u32 asw_dribble_nibble:1; // bit 26(spurious bits after EOP) | ||
175 | u32 asw_control_frame:1; // bit 27(is a control frame) | ||
176 | u32 asw_pause_frame:1; // bit 28(is a pause frame) | ||
177 | u32 asw_unsupported_op:1; // bit 29(unsupported OP code) | ||
178 | u32 asw_VLAN_tag:1; // bit 30(VLAN tag detected) | ||
179 | u32 asw_long_evt:1; // bit 31(Rx long event) | ||
180 | #if 0 | ||
181 | u32 asw_trunc:1; // bit 31(Rx frame truncated) | ||
182 | #endif | ||
183 | #endif | ||
184 | } bits; | ||
185 | } PKT_STAT_DESC_WORD0_t, *PPKT_STAT_WORD0_t; | ||
186 | |||
187 | typedef union _PKT_STAT_DESC_WORD1_t { | ||
188 | u32 value; | ||
189 | struct { | ||
190 | #ifdef _BIT_FIELDS_HTOL | ||
191 | u32 unused:4; // bits 28-31 | ||
192 | u32 ri:2; // bits 26-27(Ring Index) | ||
193 | u32 bi:10; // bits 16-25(Buffer Index) | ||
194 | u32 length:16; // bit 0-15(length in bytes) | ||
195 | #else | ||
196 | u32 length:16; // bit 0-15(length in bytes) | ||
197 | u32 bi:10; // bits 16-25(Buffer Index) | ||
198 | u32 ri:2; // bits 26-27(Ring Index) | ||
199 | u32 unused:4; // bits 28-31 | ||
200 | #endif | ||
201 | } bits; | ||
202 | } PKT_STAT_DESC_WORD1_t, *PPKT_STAT_WORD1_t; | ||
203 | |||
204 | typedef struct _PKT_STAT_DESC_t { | ||
205 | PKT_STAT_DESC_WORD0_t word0; | ||
206 | PKT_STAT_DESC_WORD1_t word1; | ||
207 | } PKT_STAT_DESC_t, *PPKT_STAT_DESC_t; | ||
208 | |||
209 | /* Typedefs for the RX DMA status word */ | ||
210 | |||
211 | /* | ||
212 | * RXSTAT_WORD0_t structure holds part of the status bits of the Rx DMA engine | ||
213 | * that get copied out to memory by the ET-1310. Word 0 is a 32 bit word | ||
214 | * whichcontains Free Buffer ring 0 and 1 available offset. | ||
215 | */ | ||
216 | typedef union _rxstat_word0_t { | ||
217 | u32 value; | ||
218 | struct { | ||
219 | #ifdef _BIT_FIELDS_HTOL | ||
220 | u32 FBR1unused:5; // bits 27-31 | ||
221 | u32 FBR1wrap:1; // bit 26 | ||
222 | u32 FBR1offset:10; // bits 16-25 | ||
223 | u32 FBR0unused:5; // bits 11-15 | ||
224 | u32 FBR0wrap:1; // bit 10 | ||
225 | u32 FBR0offset:10; // bits 0-9 | ||
226 | #else | ||
227 | u32 FBR0offset:10; // bits 0-9 | ||
228 | u32 FBR0wrap:1; // bit 10 | ||
229 | u32 FBR0unused:5; // bits 11-15 | ||
230 | u32 FBR1offset:10; // bits 16-25 | ||
231 | u32 FBR1wrap:1; // bit 26 | ||
232 | u32 FBR1unused:5; // bits 27-31 | ||
233 | #endif | ||
234 | } bits; | ||
235 | } RXSTAT_WORD0_t, *PRXSTAT_WORD0_t; | ||
236 | |||
237 | /* | ||
238 | * RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine | ||
239 | * that get copied out to memory by the ET-1310. Word 3 is a 32 bit word | ||
240 | * which contains the Packet Status Ring available offset. | ||
241 | */ | ||
242 | typedef union _rxstat_word1_t { | ||
243 | u32 value; | ||
244 | struct { | ||
245 | #ifdef _BIT_FIELDS_HTOL | ||
246 | u32 PSRunused:3; // bits 29-31 | ||
247 | u32 PSRwrap:1; // bit 28 | ||
248 | u32 PSRoffset:12; // bits 16-27 | ||
249 | u32 reserved:16; // bits 0-15 | ||
250 | #else | ||
251 | u32 reserved:16; // bits 0-15 | ||
252 | u32 PSRoffset:12; // bits 16-27 | ||
253 | u32 PSRwrap:1; // bit 28 | ||
254 | u32 PSRunused:3; // bits 29-31 | ||
255 | #endif | ||
256 | } bits; | ||
257 | } RXSTAT_WORD1_t, *PRXSTAT_WORD1_t; | ||
258 | |||
259 | /* | ||
260 | * RX_STATUS_BLOCK_t is sructure representing the status of the Rx DMA engine | ||
261 | * it sits in free memory, and is pointed to by 0x101c / 0x1020 | ||
262 | */ | ||
263 | typedef struct _rx_status_block_t { | ||
264 | RXSTAT_WORD0_t Word0; | ||
265 | RXSTAT_WORD1_t Word1; | ||
266 | } RX_STATUS_BLOCK_t, *PRX_STATUS_BLOCK_t; | ||
267 | |||
268 | /* | ||
269 | * Structure for look-up table holding free buffer ring pointers | ||
270 | */ | ||
271 | typedef struct _FbrLookupTable { | ||
272 | void *Va[MAX_DESC_PER_RING_RX]; | ||
273 | void *Buffer1[MAX_DESC_PER_RING_RX]; | ||
274 | void *Buffer2[MAX_DESC_PER_RING_RX]; | ||
275 | u32 PAHigh[MAX_DESC_PER_RING_RX]; | ||
276 | u32 PALow[MAX_DESC_PER_RING_RX]; | ||
277 | } FBRLOOKUPTABLE, *PFBRLOOKUPTABLE; | ||
278 | |||
279 | typedef enum { | ||
280 | ONE_PACKET_INTERRUPT, | ||
281 | FOUR_PACKET_INTERRUPT | ||
282 | } eRX_INTERRUPT_STATE_t, *PeRX_INTERRUPT_STATE_t; | ||
283 | |||
284 | /* | ||
285 | * Structure to hold the skb's in a list | ||
286 | */ | ||
287 | typedef struct rx_skb_list_elem { | ||
288 | struct list_head skb_list_elem; | ||
289 | dma_addr_t dma_addr; | ||
290 | struct sk_buff *skb; | ||
291 | } RX_SKB_LIST_ELEM, *PRX_SKB_LIST_ELEM; | ||
292 | |||
293 | /* | ||
294 | * RX_RING_t is sructure representing the adaptor's local reference(s) to the | ||
295 | * rings | ||
296 | */ | ||
297 | typedef struct _rx_ring_t { | ||
298 | #ifdef USE_FBR0 | ||
299 | void *pFbr0RingVa; | ||
300 | dma_addr_t pFbr0RingPa; | ||
301 | void *Fbr0MemVa[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; | ||
302 | dma_addr_t Fbr0MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; | ||
303 | uint64_t Fbr0Realpa; | ||
304 | uint64_t Fbr0offset; | ||
305 | DMA10W_t local_Fbr0_full; | ||
306 | u32 Fbr0NumEntries; | ||
307 | u32 Fbr0BufferSize; | ||
308 | #endif | ||
309 | void *pFbr1RingVa; | ||
310 | dma_addr_t pFbr1RingPa; | ||
311 | void *Fbr1MemVa[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; | ||
312 | dma_addr_t Fbr1MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; | ||
313 | uint64_t Fbr1Realpa; | ||
314 | uint64_t Fbr1offset; | ||
315 | FBRLOOKUPTABLE *Fbr[2]; | ||
316 | DMA10W_t local_Fbr1_full; | ||
317 | u32 Fbr1NumEntries; | ||
318 | u32 Fbr1BufferSize; | ||
319 | |||
320 | void *pPSRingVa; | ||
321 | dma_addr_t pPSRingPa; | ||
322 | uint64_t pPSRingRealPa; | ||
323 | uint64_t pPSRingOffset; | ||
324 | RXDMA_PSR_FULL_OFFSET_t local_psr_full; | ||
325 | u32 PsrNumEntries; | ||
326 | |||
327 | void *pRxStatusVa; | ||
328 | dma_addr_t pRxStatusPa; | ||
329 | uint64_t RxStatusRealPA; | ||
330 | uint64_t RxStatusOffset; | ||
331 | |||
332 | struct list_head RecvBufferPool; | ||
333 | |||
334 | /* RECV */ | ||
335 | struct list_head RecvList; | ||
336 | struct list_head RecvPendingList; | ||
337 | u32 nReadyRecv; | ||
338 | |||
339 | u32 NumRfd; | ||
340 | |||
341 | bool UnfinishedReceives; | ||
342 | |||
343 | struct list_head RecvPacketPool; | ||
344 | |||
345 | /* lookaside lists */ | ||
346 | struct kmem_cache *RecvLookaside; | ||
347 | } RX_RING_t, *PRX_RING_t; | ||
348 | |||
349 | /* Forward reference of RFD */ | ||
350 | struct _MP_RFD; | ||
351 | |||
352 | /* Forward declaration of the private adapter structure */ | ||
353 | struct et131x_adapter; | ||
354 | |||
355 | /* PROTOTYPES for Initialization */ | ||
356 | int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter); | ||
357 | void et131x_rx_dma_memory_free(struct et131x_adapter *adapter); | ||
358 | int et131x_rfd_resources_alloc(struct et131x_adapter *adapter, | ||
359 | struct _MP_RFD *pMpRfd); | ||
360 | void et131x_rfd_resources_free(struct et131x_adapter *adapter, | ||
361 | struct _MP_RFD *pMpRfd); | ||
362 | int et131x_init_recv(struct et131x_adapter *adapter); | ||
363 | |||
364 | void ConfigRxDmaRegs(struct et131x_adapter *adapter); | ||
365 | void SetRxDmaTimer(struct et131x_adapter *adapter); | ||
366 | void et131x_rx_dma_disable(struct et131x_adapter *adapter); | ||
367 | void et131x_rx_dma_enable(struct et131x_adapter *adapter); | ||
368 | |||
369 | void et131x_reset_recv(struct et131x_adapter *adapter); | ||
370 | |||
371 | void et131x_handle_recv_interrupt(struct et131x_adapter *adapter); | ||
372 | |||
373 | #endif /* __ET1310_RX_H__ */ | ||
diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c new file mode 100644 index 000000000000..a95c2608a0c0 --- /dev/null +++ b/drivers/staging/et131x/et1310_tx.c | |||
@@ -0,0 +1,1525 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_tx.c - Routines used to perform data transmission. | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include "et131x_version.h" | ||
59 | #include "et131x_debug.h" | ||
60 | #include "et131x_defs.h" | ||
61 | |||
62 | #include <linux/pci.h> | ||
63 | #include <linux/init.h> | ||
64 | #include <linux/module.h> | ||
65 | #include <linux/types.h> | ||
66 | #include <linux/kernel.h> | ||
67 | |||
68 | #include <linux/sched.h> | ||
69 | #include <linux/ptrace.h> | ||
70 | #include <linux/slab.h> | ||
71 | #include <linux/ctype.h> | ||
72 | #include <linux/string.h> | ||
73 | #include <linux/timer.h> | ||
74 | #include <linux/interrupt.h> | ||
75 | #include <linux/in.h> | ||
76 | #include <linux/delay.h> | ||
77 | #include <asm/io.h> | ||
78 | #include <asm/system.h> | ||
79 | #include <asm/bitops.h> | ||
80 | |||
81 | #include <linux/netdevice.h> | ||
82 | #include <linux/etherdevice.h> | ||
83 | #include <linux/skbuff.h> | ||
84 | #include <linux/if_arp.h> | ||
85 | #include <linux/ioport.h> | ||
86 | |||
87 | #include "et1310_phy.h" | ||
88 | #include "et1310_pm.h" | ||
89 | #include "et1310_jagcore.h" | ||
90 | |||
91 | #include "et131x_adapter.h" | ||
92 | #include "et131x_initpci.h" | ||
93 | #include "et131x_isr.h" | ||
94 | |||
95 | #include "et1310_tx.h" | ||
96 | |||
97 | /* Data for debugging facilities */ | ||
98 | #ifdef CONFIG_ET131X_DEBUG | ||
99 | extern dbg_info_t *et131x_dbginfo; | ||
100 | #endif /* CONFIG_ET131X_DEBUG */ | ||
101 | |||
102 | static void et131x_update_tcb_list(struct et131x_adapter *pAdapter); | ||
103 | static void et131x_check_send_wait_list(struct et131x_adapter *pAdapter); | ||
104 | static inline void et131x_free_send_packet(struct et131x_adapter *pAdapter, | ||
105 | PMP_TCB pMpTcb); | ||
106 | static int et131x_send_packet(struct sk_buff *skb, | ||
107 | struct et131x_adapter *pAdapter); | ||
108 | static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb); | ||
109 | |||
110 | /** | ||
111 | * et131x_tx_dma_memory_alloc | ||
112 | * @adapter: pointer to our private adapter structure | ||
113 | * | ||
114 | * Returns 0 on success and errno on failure (as defined in errno.h). | ||
115 | * | ||
116 | * Allocates memory that will be visible both to the device and to the CPU. | ||
117 | * The OS will pass us packets, pointers to which we will insert in the Tx | ||
118 | * Descriptor queue. The device will read this queue to find the packets in | ||
119 | * memory. The device will update the "status" in memory each time it xmits a | ||
120 | * packet. | ||
121 | */ | ||
122 | int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) | ||
123 | { | ||
124 | int desc_size = 0; | ||
125 | TX_RING_t *tx_ring = &adapter->TxRing; | ||
126 | |||
127 | DBG_ENTER(et131x_dbginfo); | ||
128 | |||
129 | /* Allocate memory for the TCB's (Transmit Control Block) */ | ||
130 | adapter->TxRing.MpTcbMem = (MP_TCB *) kcalloc(NUM_TCB, sizeof(MP_TCB), | ||
131 | GFP_ATOMIC | GFP_DMA); | ||
132 | if (!adapter->TxRing.MpTcbMem) { | ||
133 | DBG_ERROR(et131x_dbginfo, "Cannot alloc memory for TCBs\n"); | ||
134 | DBG_LEAVE(et131x_dbginfo); | ||
135 | return -ENOMEM; | ||
136 | } | ||
137 | |||
138 | /* Allocate enough memory for the Tx descriptor ring, and allocate | ||
139 | * some extra so that the ring can be aligned on a 4k boundary. | ||
140 | */ | ||
141 | desc_size = (sizeof(TX_DESC_ENTRY_t) * NUM_DESC_PER_RING_TX) + 4096 - 1; | ||
142 | tx_ring->pTxDescRingVa = | ||
143 | (PTX_DESC_ENTRY_t) pci_alloc_consistent(adapter->pdev, desc_size, | ||
144 | &tx_ring->pTxDescRingPa); | ||
145 | if (!adapter->TxRing.pTxDescRingVa) { | ||
146 | DBG_ERROR(et131x_dbginfo, "Cannot alloc memory for Tx Ring\n"); | ||
147 | DBG_LEAVE(et131x_dbginfo); | ||
148 | return -ENOMEM; | ||
149 | } | ||
150 | |||
151 | /* Save physical address | ||
152 | * | ||
153 | * NOTE: pci_alloc_consistent(), used above to alloc DMA regions, | ||
154 | * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses | ||
155 | * are ever returned, make sure the high part is retrieved here before | ||
156 | * storing the adjusted address. | ||
157 | */ | ||
158 | tx_ring->pTxDescRingAdjustedPa = tx_ring->pTxDescRingPa; | ||
159 | |||
160 | /* Align Tx Descriptor Ring on a 4k (0x1000) byte boundary */ | ||
161 | et131x_align_allocated_memory(adapter, | ||
162 | &tx_ring->pTxDescRingAdjustedPa, | ||
163 | &tx_ring->TxDescOffset, 0x0FFF); | ||
164 | |||
165 | tx_ring->pTxDescRingVa += tx_ring->TxDescOffset; | ||
166 | |||
167 | /* Allocate memory for the Tx status block */ | ||
168 | tx_ring->pTxStatusVa = pci_alloc_consistent(adapter->pdev, | ||
169 | sizeof(TX_STATUS_BLOCK_t), | ||
170 | &tx_ring->pTxStatusPa); | ||
171 | if (!adapter->TxRing.pTxStatusPa) { | ||
172 | DBG_ERROR(et131x_dbginfo, | ||
173 | "Cannot alloc memory for Tx status block\n"); | ||
174 | DBG_LEAVE(et131x_dbginfo); | ||
175 | return -ENOMEM; | ||
176 | } | ||
177 | |||
178 | /* Allocate memory for a dummy buffer */ | ||
179 | tx_ring->pTxDummyBlkVa = pci_alloc_consistent(adapter->pdev, | ||
180 | NIC_MIN_PACKET_SIZE, | ||
181 | &tx_ring->pTxDummyBlkPa); | ||
182 | if (!adapter->TxRing.pTxDummyBlkPa) { | ||
183 | DBG_ERROR(et131x_dbginfo, | ||
184 | "Cannot alloc memory for Tx dummy buffer\n"); | ||
185 | DBG_LEAVE(et131x_dbginfo); | ||
186 | return -ENOMEM; | ||
187 | } | ||
188 | |||
189 | DBG_LEAVE(et131x_dbginfo); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * et131x_tx_dma_memory_free - Free all memory allocated within this module | ||
195 | * @adapter: pointer to our private adapter structure | ||
196 | * | ||
197 | * Returns 0 on success and errno on failure (as defined in errno.h). | ||
198 | */ | ||
199 | void et131x_tx_dma_memory_free(struct et131x_adapter *adapter) | ||
200 | { | ||
201 | int desc_size = 0; | ||
202 | |||
203 | DBG_ENTER(et131x_dbginfo); | ||
204 | |||
205 | if (adapter->TxRing.pTxDescRingVa) { | ||
206 | /* Free memory relating to Tx rings here */ | ||
207 | adapter->TxRing.pTxDescRingVa -= adapter->TxRing.TxDescOffset; | ||
208 | |||
209 | desc_size = | ||
210 | (sizeof(TX_DESC_ENTRY_t) * NUM_DESC_PER_RING_TX) + 4096 - 1; | ||
211 | |||
212 | pci_free_consistent(adapter->pdev, | ||
213 | desc_size, | ||
214 | adapter->TxRing.pTxDescRingVa, | ||
215 | adapter->TxRing.pTxDescRingPa); | ||
216 | |||
217 | adapter->TxRing.pTxDescRingVa = NULL; | ||
218 | } | ||
219 | |||
220 | /* Free memory for the Tx status block */ | ||
221 | if (adapter->TxRing.pTxStatusVa) { | ||
222 | pci_free_consistent(adapter->pdev, | ||
223 | sizeof(TX_STATUS_BLOCK_t), | ||
224 | adapter->TxRing.pTxStatusVa, | ||
225 | adapter->TxRing.pTxStatusPa); | ||
226 | |||
227 | adapter->TxRing.pTxStatusVa = NULL; | ||
228 | } | ||
229 | |||
230 | /* Free memory for the dummy buffer */ | ||
231 | if (adapter->TxRing.pTxDummyBlkVa) { | ||
232 | pci_free_consistent(adapter->pdev, | ||
233 | NIC_MIN_PACKET_SIZE, | ||
234 | adapter->TxRing.pTxDummyBlkVa, | ||
235 | adapter->TxRing.pTxDummyBlkPa); | ||
236 | |||
237 | adapter->TxRing.pTxDummyBlkVa = NULL; | ||
238 | } | ||
239 | |||
240 | /* Free the memory for MP_TCB structures */ | ||
241 | if (adapter->TxRing.MpTcbMem) { | ||
242 | kfree(adapter->TxRing.MpTcbMem); | ||
243 | adapter->TxRing.MpTcbMem = NULL; | ||
244 | } | ||
245 | |||
246 | DBG_LEAVE(et131x_dbginfo); | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * ConfigTxDmaRegs - Set up the tx dma section of the JAGCore. | ||
251 | * @adapter: pointer to our private adapter structure | ||
252 | */ | ||
253 | void ConfigTxDmaRegs(struct et131x_adapter *pAdapter) | ||
254 | { | ||
255 | struct _TXDMA_t __iomem *pTxDma = &pAdapter->CSRAddress->txdma; | ||
256 | |||
257 | DBG_ENTER(et131x_dbginfo); | ||
258 | |||
259 | /* Load the hardware with the start of the transmit descriptor ring. */ | ||
260 | writel((uint32_t) (pAdapter->TxRing.pTxDescRingAdjustedPa >> 32), | ||
261 | &pTxDma->pr_base_hi); | ||
262 | writel((uint32_t) pAdapter->TxRing.pTxDescRingAdjustedPa, | ||
263 | &pTxDma->pr_base_lo); | ||
264 | |||
265 | /* Initialise the transmit DMA engine */ | ||
266 | writel(NUM_DESC_PER_RING_TX - 1, &pTxDma->pr_num_des.value); | ||
267 | |||
268 | /* Load the completion writeback physical address | ||
269 | * | ||
270 | * NOTE: pci_alloc_consistent(), used above to alloc DMA regions, | ||
271 | * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses | ||
272 | * are ever returned, make sure the high part is retrieved here before | ||
273 | * storing the adjusted address. | ||
274 | */ | ||
275 | writel(0, &pTxDma->dma_wb_base_hi); | ||
276 | writel(pAdapter->TxRing.pTxStatusPa, &pTxDma->dma_wb_base_lo); | ||
277 | |||
278 | memset(pAdapter->TxRing.pTxStatusVa, 0, sizeof(TX_STATUS_BLOCK_t)); | ||
279 | |||
280 | writel(0, &pTxDma->service_request.value); | ||
281 | pAdapter->TxRing.txDmaReadyToSend.value = 0; | ||
282 | |||
283 | DBG_LEAVE(et131x_dbginfo); | ||
284 | } | ||
285 | |||
286 | /** | ||
287 | * et131x_tx_dma_disable - Stop of Tx_DMA on the ET1310 | ||
288 | * @pAdapter: pointer to our adapter structure | ||
289 | */ | ||
290 | void et131x_tx_dma_disable(struct et131x_adapter *pAdapter) | ||
291 | { | ||
292 | DBG_ENTER(et131x_dbginfo); | ||
293 | |||
294 | /* Setup the tramsmit dma configuration register */ | ||
295 | writel(0x101, &pAdapter->CSRAddress->txdma.csr.value); | ||
296 | |||
297 | DBG_LEAVE(et131x_dbginfo); | ||
298 | } | ||
299 | |||
300 | /** | ||
301 | * et131x_tx_dma_enable - re-start of Tx_DMA on the ET1310. | ||
302 | * @pAdapter: pointer to our adapter structure | ||
303 | * | ||
304 | * Mainly used after a return to the D0 (full-power) state from a lower state. | ||
305 | */ | ||
306 | void et131x_tx_dma_enable(struct et131x_adapter *pAdapter) | ||
307 | { | ||
308 | DBG_ENTER(et131x_dbginfo); | ||
309 | |||
310 | if (pAdapter->RegistryPhyLoopbk) { | ||
311 | /* TxDMA is disabled for loopback operation. */ | ||
312 | writel(0x101, &pAdapter->CSRAddress->txdma.csr.value); | ||
313 | } else { | ||
314 | TXDMA_CSR_t csr = { 0 }; | ||
315 | |||
316 | /* Setup the transmit dma configuration register for normal | ||
317 | * operation | ||
318 | */ | ||
319 | csr.bits.sngl_epkt_mode = 1; | ||
320 | csr.bits.halt = 0; | ||
321 | csr.bits.cache_thrshld = pAdapter->RegistryDMACache; | ||
322 | writel(csr.value, &pAdapter->CSRAddress->txdma.csr.value); | ||
323 | } | ||
324 | |||
325 | DBG_LEAVE(et131x_dbginfo); | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * et131x_init_send - Initialize send data structures | ||
330 | * @adapter: pointer to our private adapter structure | ||
331 | */ | ||
332 | void et131x_init_send(struct et131x_adapter *adapter) | ||
333 | { | ||
334 | PMP_TCB pMpTcb; | ||
335 | uint32_t TcbCount; | ||
336 | TX_RING_t *tx_ring; | ||
337 | |||
338 | DBG_ENTER(et131x_dbginfo); | ||
339 | |||
340 | /* Setup some convenience pointers */ | ||
341 | tx_ring = &adapter->TxRing; | ||
342 | pMpTcb = adapter->TxRing.MpTcbMem; | ||
343 | |||
344 | tx_ring->TCBReadyQueueHead = pMpTcb; | ||
345 | |||
346 | /* Go through and set up each TCB */ | ||
347 | for (TcbCount = 0; TcbCount < NUM_TCB; TcbCount++) { | ||
348 | memset(pMpTcb, 0, sizeof(MP_TCB)); | ||
349 | |||
350 | /* Set the link pointer in HW TCB to the next TCB in the | ||
351 | * chain. If this is the last TCB in the chain, also set the | ||
352 | * tail pointer. | ||
353 | */ | ||
354 | if (TcbCount < NUM_TCB - 1) { | ||
355 | pMpTcb->Next = pMpTcb + 1; | ||
356 | } else { | ||
357 | tx_ring->TCBReadyQueueTail = pMpTcb; | ||
358 | pMpTcb->Next = (PMP_TCB) NULL; | ||
359 | } | ||
360 | |||
361 | pMpTcb++; | ||
362 | } | ||
363 | |||
364 | /* Curr send queue should now be empty */ | ||
365 | tx_ring->CurrSendHead = (PMP_TCB) NULL; | ||
366 | tx_ring->CurrSendTail = (PMP_TCB) NULL; | ||
367 | |||
368 | INIT_LIST_HEAD(&adapter->TxRing.SendWaitQueue); | ||
369 | |||
370 | DBG_LEAVE(et131x_dbginfo); | ||
371 | } | ||
372 | |||
373 | /** | ||
374 | * et131x_send_packets - This function is called by the OS to send packets | ||
375 | * @skb: the packet(s) to send | ||
376 | * @netdev:device on which to TX the above packet(s) | ||
377 | * | ||
378 | * Return 0 in almost all cases; non-zero value in extreme hard failure only | ||
379 | */ | ||
380 | int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev) | ||
381 | { | ||
382 | int status = 0; | ||
383 | struct et131x_adapter *pAdapter = NULL; | ||
384 | |||
385 | DBG_TX_ENTER(et131x_dbginfo); | ||
386 | |||
387 | pAdapter = netdev_priv(netdev); | ||
388 | |||
389 | /* Send these packets | ||
390 | * | ||
391 | * NOTE: The Linux Tx entry point is only given one packet at a time | ||
392 | * to Tx, so the PacketCount and it's array used makes no sense here | ||
393 | */ | ||
394 | |||
395 | /* Queue is not empty or TCB is not available */ | ||
396 | if (!list_empty(&pAdapter->TxRing.SendWaitQueue) || | ||
397 | MP_TCB_RESOURCES_NOT_AVAILABLE(pAdapter)) { | ||
398 | /* NOTE: If there's an error on send, no need to queue the | ||
399 | * packet under Linux; if we just send an error up to the | ||
400 | * netif layer, it will resend the skb to us. | ||
401 | */ | ||
402 | DBG_VERBOSE(et131x_dbginfo, "TCB Resources Not Available\n"); | ||
403 | status = -ENOMEM; | ||
404 | } else { | ||
405 | /* We need to see if the link is up; if it's not, make the | ||
406 | * netif layer think we're good and drop the packet | ||
407 | */ | ||
408 | //if( MP_SHOULD_FAIL_SEND( pAdapter ) || pAdapter->DriverNoPhyAccess ) | ||
409 | if (MP_SHOULD_FAIL_SEND(pAdapter) || pAdapter->DriverNoPhyAccess | ||
410 | || !netif_carrier_ok(netdev)) { | ||
411 | DBG_VERBOSE(et131x_dbginfo, | ||
412 | "Can't Tx, Link is DOWN; drop the packet\n"); | ||
413 | |||
414 | dev_kfree_skb_any(skb); | ||
415 | skb = NULL; | ||
416 | |||
417 | pAdapter->net_stats.tx_dropped++; | ||
418 | } else { | ||
419 | status = et131x_send_packet(skb, pAdapter); | ||
420 | |||
421 | if (status == -ENOMEM) { | ||
422 | |||
423 | /* NOTE: If there's an error on send, no need | ||
424 | * to queue the packet under Linux; if we just | ||
425 | * send an error up to the netif layer, it | ||
426 | * will resend the skb to us. | ||
427 | */ | ||
428 | DBG_WARNING(et131x_dbginfo, | ||
429 | "Resources problem, Queue tx packet\n"); | ||
430 | } else if (status != 0) { | ||
431 | /* On any other error, make netif think we're | ||
432 | * OK and drop the packet | ||
433 | */ | ||
434 | DBG_WARNING(et131x_dbginfo, | ||
435 | "General error, drop packet\n"); | ||
436 | |||
437 | dev_kfree_skb_any(skb); | ||
438 | skb = NULL; | ||
439 | |||
440 | pAdapter->net_stats.tx_dropped++; | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | |||
445 | DBG_TX_LEAVE(et131x_dbginfo); | ||
446 | return status; | ||
447 | } | ||
448 | |||
449 | /** | ||
450 | * et131x_send_packet - Do the work to send a packet | ||
451 | * @skb: the packet(s) to send | ||
452 | * @pAdapter: a pointer to the device's private adapter structure | ||
453 | * | ||
454 | * Return 0 in almost all cases; non-zero value in extreme hard failure only. | ||
455 | * | ||
456 | * Assumption: Send spinlock has been acquired | ||
457 | */ | ||
458 | static int et131x_send_packet(struct sk_buff *skb, | ||
459 | struct et131x_adapter *pAdapter) | ||
460 | { | ||
461 | int status = 0; | ||
462 | PMP_TCB pMpTcb = NULL; | ||
463 | uint16_t *pShBufVa; | ||
464 | unsigned long lockflags; | ||
465 | |||
466 | DBG_TX_ENTER(et131x_dbginfo); | ||
467 | |||
468 | /* Is our buffer scattered, or continuous? */ | ||
469 | if (skb_shinfo(skb)->nr_frags == 0) { | ||
470 | DBG_TX(et131x_dbginfo, "Scattered buffer: NO\n"); | ||
471 | } else { | ||
472 | DBG_TX(et131x_dbginfo, "Scattered buffer: YES, Num Frags: %d\n", | ||
473 | skb_shinfo(skb)->nr_frags); | ||
474 | } | ||
475 | |||
476 | /* All packets must have at least a MAC address and a protocol type */ | ||
477 | if (skb->len < ETH_HLEN) { | ||
478 | DBG_ERROR(et131x_dbginfo, | ||
479 | "Packet size < ETH_HLEN (14 bytes)\n"); | ||
480 | DBG_LEAVE(et131x_dbginfo); | ||
481 | return -EIO; | ||
482 | } | ||
483 | |||
484 | /* Get a TCB for this packet */ | ||
485 | spin_lock_irqsave(&pAdapter->TCBReadyQLock, lockflags); | ||
486 | |||
487 | pMpTcb = pAdapter->TxRing.TCBReadyQueueHead; | ||
488 | |||
489 | if (pMpTcb == NULL) { | ||
490 | spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags); | ||
491 | |||
492 | DBG_WARNING(et131x_dbginfo, "Can't obtain a TCB\n"); | ||
493 | DBG_TX_LEAVE(et131x_dbginfo); | ||
494 | return -ENOMEM; | ||
495 | } | ||
496 | |||
497 | pAdapter->TxRing.TCBReadyQueueHead = pMpTcb->Next; | ||
498 | |||
499 | if (pAdapter->TxRing.TCBReadyQueueHead == NULL) { | ||
500 | pAdapter->TxRing.TCBReadyQueueTail = NULL; | ||
501 | } | ||
502 | |||
503 | spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags); | ||
504 | |||
505 | pMpTcb->PacketLength = skb->len; | ||
506 | pMpTcb->Packet = skb; | ||
507 | |||
508 | if ((skb->data != NULL) && ((skb->len - skb->data_len) >= 6)) { | ||
509 | pShBufVa = (uint16_t *) skb->data; | ||
510 | |||
511 | if ((pShBufVa[0] == 0xffff) && | ||
512 | (pShBufVa[1] == 0xffff) && (pShBufVa[2] == 0xffff)) { | ||
513 | MP_SET_FLAG(pMpTcb, fMP_DEST_BROAD); | ||
514 | } else if ((pShBufVa[0] & 0x3) == 0x0001) { | ||
515 | MP_SET_FLAG(pMpTcb, fMP_DEST_MULTI); | ||
516 | } | ||
517 | } | ||
518 | |||
519 | pMpTcb->Next = NULL; | ||
520 | |||
521 | /* Call the NIC specific send handler. */ | ||
522 | if (status == 0) { | ||
523 | status = nic_send_packet(pAdapter, pMpTcb); | ||
524 | } | ||
525 | |||
526 | if (status != 0) { | ||
527 | spin_lock_irqsave(&pAdapter->TCBReadyQLock, lockflags); | ||
528 | |||
529 | if (pAdapter->TxRing.TCBReadyQueueTail) { | ||
530 | pAdapter->TxRing.TCBReadyQueueTail->Next = pMpTcb; | ||
531 | } else { | ||
532 | /* Apparently ready Q is empty. */ | ||
533 | pAdapter->TxRing.TCBReadyQueueHead = pMpTcb; | ||
534 | } | ||
535 | |||
536 | pAdapter->TxRing.TCBReadyQueueTail = pMpTcb; | ||
537 | |||
538 | spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags); | ||
539 | |||
540 | DBG_TX_LEAVE(et131x_dbginfo); | ||
541 | return status; | ||
542 | } | ||
543 | |||
544 | DBG_ASSERT(pAdapter->TxRing.nBusySend <= NUM_TCB); | ||
545 | |||
546 | DBG_TX_LEAVE(et131x_dbginfo); | ||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | /** | ||
551 | * nic_send_packet - NIC specific send handler for version B silicon. | ||
552 | * @pAdapter: pointer to our adapter | ||
553 | * @pMpTcb: pointer to MP_TCB | ||
554 | * | ||
555 | * Returns 0 or errno. | ||
556 | */ | ||
557 | static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb) | ||
558 | { | ||
559 | uint32_t loopIndex; | ||
560 | TX_DESC_ENTRY_t CurDesc[24]; | ||
561 | uint32_t FragmentNumber = 0; | ||
562 | uint32_t iThisCopy, iRemainder; | ||
563 | struct sk_buff *pPacket = pMpTcb->Packet; | ||
564 | uint32_t FragListCount = skb_shinfo(pPacket)->nr_frags + 1; | ||
565 | struct skb_frag_struct *pFragList = &skb_shinfo(pPacket)->frags[0]; | ||
566 | unsigned long lockflags1, lockflags2; | ||
567 | |||
568 | DBG_TX_ENTER(et131x_dbginfo); | ||
569 | |||
570 | /* Part of the optimizations of this send routine restrict us to | ||
571 | * sending 24 fragments at a pass. In practice we should never see | ||
572 | * more than 5 fragments. | ||
573 | * | ||
574 | * NOTE: The older version of this function (below) can handle any | ||
575 | * number of fragments. If needed, we can call this function, | ||
576 | * although it is less efficient. | ||
577 | */ | ||
578 | if (FragListCount > 23) { | ||
579 | DBG_TX_LEAVE(et131x_dbginfo); | ||
580 | return -EIO; | ||
581 | } | ||
582 | |||
583 | memset(CurDesc, 0, sizeof(TX_DESC_ENTRY_t) * (FragListCount + 1)); | ||
584 | |||
585 | for (loopIndex = 0; loopIndex < FragListCount; loopIndex++) { | ||
586 | /* If there is something in this element, lets get a | ||
587 | * descriptor from the ring and get the necessary data | ||
588 | */ | ||
589 | if (loopIndex == 0) { | ||
590 | /* If the fragments are smaller than a standard MTU, | ||
591 | * then map them to a single descriptor in the Tx | ||
592 | * Desc ring. However, if they're larger, as is | ||
593 | * possible with support for jumbo packets, then | ||
594 | * split them each across 2 descriptors. | ||
595 | * | ||
596 | * This will work until we determine why the hardware | ||
597 | * doesn't seem to like large fragments. | ||
598 | */ | ||
599 | if ((pPacket->len - pPacket->data_len) <= 1514) { | ||
600 | DBG_TX(et131x_dbginfo, | ||
601 | "Got packet of length %d, " | ||
602 | "filling desc entry %d, " | ||
603 | "TCB: 0x%p\n", | ||
604 | (pPacket->len - pPacket->data_len), | ||
605 | pAdapter->TxRing.txDmaReadyToSend.bits. | ||
606 | val, pMpTcb); | ||
607 | |||
608 | CurDesc[FragmentNumber].DataBufferPtrHigh = 0; | ||
609 | |||
610 | CurDesc[FragmentNumber].word2.bits. | ||
611 | length_in_bytes = | ||
612 | pPacket->len - pPacket->data_len; | ||
613 | |||
614 | /* NOTE: Here, the dma_addr_t returned from | ||
615 | * pci_map_single() is implicitly cast as a | ||
616 | * uint32_t. Although dma_addr_t can be | ||
617 | * 64-bit, the address returned by | ||
618 | * pci_map_single() is always 32-bit | ||
619 | * addressable (as defined by the pci/dma | ||
620 | * subsystem) | ||
621 | */ | ||
622 | CurDesc[FragmentNumber++].DataBufferPtrLow = | ||
623 | pci_map_single(pAdapter->pdev, | ||
624 | pPacket->data, | ||
625 | pPacket->len - | ||
626 | pPacket->data_len, | ||
627 | PCI_DMA_TODEVICE); | ||
628 | } else { | ||
629 | DBG_TX(et131x_dbginfo, | ||
630 | "Got packet of length %d, " | ||
631 | "filling desc entry %d, " | ||
632 | "TCB: 0x%p\n", | ||
633 | (pPacket->len - pPacket->data_len), | ||
634 | pAdapter->TxRing.txDmaReadyToSend.bits. | ||
635 | val, pMpTcb); | ||
636 | |||
637 | CurDesc[FragmentNumber].DataBufferPtrHigh = 0; | ||
638 | |||
639 | CurDesc[FragmentNumber].word2.bits. | ||
640 | length_in_bytes = | ||
641 | ((pPacket->len - pPacket->data_len) / 2); | ||
642 | |||
643 | /* NOTE: Here, the dma_addr_t returned from | ||
644 | * pci_map_single() is implicitly cast as a | ||
645 | * uint32_t. Although dma_addr_t can be | ||
646 | * 64-bit, the address returned by | ||
647 | * pci_map_single() is always 32-bit | ||
648 | * addressable (as defined by the pci/dma | ||
649 | * subsystem) | ||
650 | */ | ||
651 | CurDesc[FragmentNumber++].DataBufferPtrLow = | ||
652 | pci_map_single(pAdapter->pdev, | ||
653 | pPacket->data, | ||
654 | ((pPacket->len - | ||
655 | pPacket->data_len) / 2), | ||
656 | PCI_DMA_TODEVICE); | ||
657 | CurDesc[FragmentNumber].DataBufferPtrHigh = 0; | ||
658 | |||
659 | CurDesc[FragmentNumber].word2.bits. | ||
660 | length_in_bytes = | ||
661 | ((pPacket->len - pPacket->data_len) / 2); | ||
662 | |||
663 | /* NOTE: Here, the dma_addr_t returned from | ||
664 | * pci_map_single() is implicitly cast as a | ||
665 | * uint32_t. Although dma_addr_t can be | ||
666 | * 64-bit, the address returned by | ||
667 | * pci_map_single() is always 32-bit | ||
668 | * addressable (as defined by the pci/dma | ||
669 | * subsystem) | ||
670 | */ | ||
671 | CurDesc[FragmentNumber++].DataBufferPtrLow = | ||
672 | pci_map_single(pAdapter->pdev, | ||
673 | pPacket->data + | ||
674 | ((pPacket->len - | ||
675 | pPacket->data_len) / 2), | ||
676 | ((pPacket->len - | ||
677 | pPacket->data_len) / 2), | ||
678 | PCI_DMA_TODEVICE); | ||
679 | } | ||
680 | } else { | ||
681 | DBG_TX(et131x_dbginfo, | ||
682 | "Got packet of length %d," | ||
683 | "filling desc entry %d\n" | ||
684 | "TCB: 0x%p\n", | ||
685 | pFragList[loopIndex].size, | ||
686 | pAdapter->TxRing.txDmaReadyToSend.bits.val, | ||
687 | pMpTcb); | ||
688 | |||
689 | CurDesc[FragmentNumber].DataBufferPtrHigh = 0; | ||
690 | |||
691 | CurDesc[FragmentNumber].word2.bits.length_in_bytes = | ||
692 | pFragList[loopIndex - 1].size; | ||
693 | |||
694 | /* NOTE: Here, the dma_addr_t returned from | ||
695 | * pci_map_page() is implicitly cast as a uint32_t. | ||
696 | * Although dma_addr_t can be 64-bit, the address | ||
697 | * returned by pci_map_page() is always 32-bit | ||
698 | * addressable (as defined by the pci/dma subsystem) | ||
699 | */ | ||
700 | CurDesc[FragmentNumber++].DataBufferPtrLow = | ||
701 | pci_map_page(pAdapter->pdev, | ||
702 | pFragList[loopIndex - 1].page, | ||
703 | pFragList[loopIndex - 1].page_offset, | ||
704 | pFragList[loopIndex - 1].size, | ||
705 | PCI_DMA_TODEVICE); | ||
706 | } | ||
707 | } | ||
708 | |||
709 | if (FragmentNumber == 0) { | ||
710 | DBG_WARNING(et131x_dbginfo, "No. frags is 0\n"); | ||
711 | return -EIO; | ||
712 | } | ||
713 | |||
714 | if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) { | ||
715 | if (++pAdapter->TxRing.TxPacketsSinceLastinterrupt == | ||
716 | pAdapter->RegistryTxNumBuffers) { | ||
717 | CurDesc[FragmentNumber - 1].word3.value = 0x5; | ||
718 | pAdapter->TxRing.TxPacketsSinceLastinterrupt = 0; | ||
719 | } else { | ||
720 | CurDesc[FragmentNumber - 1].word3.value = 0x1; | ||
721 | } | ||
722 | } else { | ||
723 | CurDesc[FragmentNumber - 1].word3.value = 0x5; | ||
724 | } | ||
725 | |||
726 | CurDesc[0].word3.bits.f = 1; | ||
727 | |||
728 | pMpTcb->WrIndexStart = pAdapter->TxRing.txDmaReadyToSend; | ||
729 | pMpTcb->PacketStaleCount = 0; | ||
730 | |||
731 | spin_lock_irqsave(&pAdapter->SendHWLock, lockflags1); | ||
732 | |||
733 | iThisCopy = | ||
734 | NUM_DESC_PER_RING_TX - pAdapter->TxRing.txDmaReadyToSend.bits.val; | ||
735 | |||
736 | if (iThisCopy >= FragmentNumber) { | ||
737 | iRemainder = 0; | ||
738 | iThisCopy = FragmentNumber; | ||
739 | } else { | ||
740 | iRemainder = FragmentNumber - iThisCopy; | ||
741 | } | ||
742 | |||
743 | memcpy(pAdapter->TxRing.pTxDescRingVa + | ||
744 | pAdapter->TxRing.txDmaReadyToSend.bits.val, CurDesc, | ||
745 | sizeof(TX_DESC_ENTRY_t) * iThisCopy); | ||
746 | |||
747 | pAdapter->TxRing.txDmaReadyToSend.bits.val += iThisCopy; | ||
748 | |||
749 | if ((pAdapter->TxRing.txDmaReadyToSend.bits.val == 0) || | ||
750 | (pAdapter->TxRing.txDmaReadyToSend.bits.val == | ||
751 | NUM_DESC_PER_RING_TX)) { | ||
752 | if (pAdapter->TxRing.txDmaReadyToSend.bits.wrap) { | ||
753 | pAdapter->TxRing.txDmaReadyToSend.value = 0; | ||
754 | } else { | ||
755 | pAdapter->TxRing.txDmaReadyToSend.value = 0x400; | ||
756 | } | ||
757 | } | ||
758 | |||
759 | if (iRemainder) { | ||
760 | memcpy(pAdapter->TxRing.pTxDescRingVa, | ||
761 | CurDesc + iThisCopy, | ||
762 | sizeof(TX_DESC_ENTRY_t) * iRemainder); | ||
763 | |||
764 | pAdapter->TxRing.txDmaReadyToSend.bits.val += iRemainder; | ||
765 | } | ||
766 | |||
767 | if (pAdapter->TxRing.txDmaReadyToSend.bits.val == 0) { | ||
768 | if (pAdapter->TxRing.txDmaReadyToSend.value) { | ||
769 | pMpTcb->WrIndex.value = NUM_DESC_PER_RING_TX - 1; | ||
770 | } else { | ||
771 | pMpTcb->WrIndex.value = | ||
772 | 0x400 | (NUM_DESC_PER_RING_TX - 1); | ||
773 | } | ||
774 | } else { | ||
775 | pMpTcb->WrIndex.value = | ||
776 | pAdapter->TxRing.txDmaReadyToSend.value - 1; | ||
777 | } | ||
778 | |||
779 | spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags2); | ||
780 | |||
781 | if (pAdapter->TxRing.CurrSendTail) { | ||
782 | pAdapter->TxRing.CurrSendTail->Next = pMpTcb; | ||
783 | } else { | ||
784 | pAdapter->TxRing.CurrSendHead = pMpTcb; | ||
785 | } | ||
786 | |||
787 | pAdapter->TxRing.CurrSendTail = pMpTcb; | ||
788 | |||
789 | DBG_ASSERT(pMpTcb->Next == NULL); | ||
790 | |||
791 | pAdapter->TxRing.nBusySend++; | ||
792 | |||
793 | spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags2); | ||
794 | |||
795 | /* Write the new write pointer back to the device. */ | ||
796 | writel(pAdapter->TxRing.txDmaReadyToSend.value, | ||
797 | &pAdapter->CSRAddress->txdma.service_request.value); | ||
798 | |||
799 | /* For Gig only, we use Tx Interrupt coalescing. Enable the software | ||
800 | * timer to wake us up if this packet isn't followed by N more. | ||
801 | */ | ||
802 | if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) { | ||
803 | writel(pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO, | ||
804 | &pAdapter->CSRAddress->global.watchdog_timer); | ||
805 | } | ||
806 | |||
807 | spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags1); | ||
808 | |||
809 | DBG_TX_LEAVE(et131x_dbginfo); | ||
810 | return 0; | ||
811 | } | ||
812 | |||
813 | /* | ||
814 | * NOTE: For now, keep this older version of NICSendPacket around for | ||
815 | * reference, even though it's not used | ||
816 | */ | ||
817 | #if 0 | ||
818 | |||
819 | /** | ||
820 | * NICSendPacket - NIC specific send handler. | ||
821 | * @pAdapter: pointer to our adapter | ||
822 | * @pMpTcb: pointer to MP_TCB | ||
823 | * | ||
824 | * Returns 0 on succes, errno on failure. | ||
825 | * | ||
826 | * This version of the send routine is designed for version A silicon. | ||
827 | * Assumption - Send spinlock has been acquired. | ||
828 | */ | ||
829 | static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb) | ||
830 | { | ||
831 | uint32_t loopIndex, fragIndex, loopEnd; | ||
832 | uint32_t iSplitFirstElement = 0; | ||
833 | uint32_t SegmentSize = 0; | ||
834 | TX_DESC_ENTRY_t CurDesc; | ||
835 | TX_DESC_ENTRY_t *CurDescPostCopy = NULL; | ||
836 | uint32_t SlotsAvailable; | ||
837 | DMA10W_t ServiceComplete; | ||
838 | unsigned int lockflags1, lockflags2; | ||
839 | struct sk_buff *pPacket = pMpTcb->Packet; | ||
840 | uint32_t FragListCount = skb_shinfo(pPacket)->nr_frags + 1; | ||
841 | struct skb_frag_struct *pFragList = &skb_shinfo(pPacket)->frags[0]; | ||
842 | |||
843 | DBG_TX_ENTER(et131x_dbginfo); | ||
844 | |||
845 | ServiceComplete.value = | ||
846 | readl(&pAdapter->CSRAddress->txdma.NewServiceComplete.value); | ||
847 | |||
848 | /* | ||
849 | * Attempt to fix TWO hardware bugs: | ||
850 | * 1) NEVER write an odd number of descriptors. | ||
851 | * 2) If packet length is less than NIC_MIN_PACKET_SIZE, then pad the | ||
852 | * packet to NIC_MIN_PACKET_SIZE bytes by adding a new last | ||
853 | * descriptor IN HALF DUPLEX MODE ONLY | ||
854 | * NOTE that (2) interacts with (1). If the packet is less than | ||
855 | * NIC_MIN_PACKET_SIZE bytes then we will append a descriptor. | ||
856 | * Therefore if it is even now, it will eventually end up odd, and | ||
857 | * so will need adjusting. | ||
858 | * | ||
859 | * VLAN tags get involved since VLAN tags add another one or two | ||
860 | * segments. | ||
861 | */ | ||
862 | DBG_TX(et131x_dbginfo, | ||
863 | "pMpTcb->PacketLength: %d\n", pMpTcb->PacketLength); | ||
864 | |||
865 | if ((pAdapter->uiDuplexMode == 0) | ||
866 | && (pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE)) { | ||
867 | DBG_TX(et131x_dbginfo, | ||
868 | "HALF DUPLEX mode AND len < MIN_PKT_SIZE\n"); | ||
869 | if ((FragListCount & 0x1) == 0) { | ||
870 | DBG_TX(et131x_dbginfo, | ||
871 | "Even number of descs, split 1st elem\n"); | ||
872 | iSplitFirstElement = 1; | ||
873 | //SegmentSize = pFragList[0].size / 2; | ||
874 | SegmentSize = (pPacket->len - pPacket->data_len) / 2; | ||
875 | } | ||
876 | } else if (FragListCount & 0x1) { | ||
877 | DBG_TX(et131x_dbginfo, "Odd number of descs, split 1st elem\n"); | ||
878 | |||
879 | iSplitFirstElement = 1; | ||
880 | //SegmentSize = pFragList[0].size / 2; | ||
881 | SegmentSize = (pPacket->len - pPacket->data_len) / 2; | ||
882 | } | ||
883 | |||
884 | spin_lock_irqsave(&pAdapter->SendHWLock, lockflags1); | ||
885 | |||
886 | if (pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap == | ||
887 | ServiceComplete.bits.serv_cpl_wrap) { | ||
888 | /* The ring hasn't wrapped. Slots available should be | ||
889 | * (RING_SIZE) - the difference between the two pointers. | ||
890 | */ | ||
891 | SlotsAvailable = NUM_DESC_PER_RING_TX - | ||
892 | (pAdapter->TxRing.txDmaReadyToSend.bits.serv_req - | ||
893 | ServiceComplete.bits.serv_cpl); | ||
894 | } else { | ||
895 | /* The ring has wrapped. Slots available should be the | ||
896 | * difference between the two pointers. | ||
897 | */ | ||
898 | SlotsAvailable = ServiceComplete.bits.serv_cpl - | ||
899 | pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; | ||
900 | } | ||
901 | |||
902 | if ((FragListCount + iSplitFirstElement) > SlotsAvailable) { | ||
903 | DBG_WARNING(et131x_dbginfo, | ||
904 | "Not Enough Space in Tx Desc Ring\n"); | ||
905 | spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags1); | ||
906 | return -ENOMEM; | ||
907 | } | ||
908 | |||
909 | loopEnd = (FragListCount) + iSplitFirstElement; | ||
910 | fragIndex = 0; | ||
911 | |||
912 | DBG_TX(et131x_dbginfo, | ||
913 | "TCB : 0x%p\n" | ||
914 | "Packet (SKB) : 0x%p\t Packet->len: %d\t Packet->data_len: %d\n" | ||
915 | "FragListCount : %d\t iSplitFirstElement: %d\t loopEnd:%d\n", | ||
916 | pMpTcb, | ||
917 | pPacket, pPacket->len, pPacket->data_len, | ||
918 | FragListCount, iSplitFirstElement, loopEnd); | ||
919 | |||
920 | for (loopIndex = 0; loopIndex < loopEnd; loopIndex++) { | ||
921 | if (loopIndex > iSplitFirstElement) { | ||
922 | fragIndex++; | ||
923 | } | ||
924 | |||
925 | DBG_TX(et131x_dbginfo, | ||
926 | "In loop, loopIndex: %d\t fragIndex: %d\n", loopIndex, | ||
927 | fragIndex); | ||
928 | |||
929 | /* If there is something in this element, let's get a | ||
930 | * descriptor from the ring and get the necessary data | ||
931 | */ | ||
932 | DBG_TX(et131x_dbginfo, | ||
933 | "Packet Length %d," | ||
934 | "filling desc entry %d\n", | ||
935 | pPacket->len, | ||
936 | pAdapter->TxRing.txDmaReadyToSend.bits.serv_req); | ||
937 | |||
938 | // NOTE - Should we do a paranoia check here to make sure the fragment | ||
939 | // actually has a length? It's HIGHLY unlikely the fragment would | ||
940 | // contain no data... | ||
941 | if (1) { | ||
942 | // NOTE - Currently always getting 32-bit addrs, and dma_addr_t is | ||
943 | // only 32-bit, so leave "high" ptr value out for now | ||
944 | CurDesc.DataBufferPtrHigh = 0; | ||
945 | |||
946 | CurDesc.word2.value = 0; | ||
947 | CurDesc.word3.value = 0; | ||
948 | |||
949 | if (fragIndex == 0) { | ||
950 | if (iSplitFirstElement) { | ||
951 | DBG_TX(et131x_dbginfo, | ||
952 | "Split first element: YES\n"); | ||
953 | |||
954 | if (loopIndex == 0) { | ||
955 | DBG_TX(et131x_dbginfo, | ||
956 | "Got fragment of length %d, fragIndex: %d\n", | ||
957 | pPacket->len - | ||
958 | pPacket->data_len, | ||
959 | fragIndex); | ||
960 | DBG_TX(et131x_dbginfo, | ||
961 | "SegmentSize: %d\n", | ||
962 | SegmentSize); | ||
963 | |||
964 | CurDesc.word2.bits. | ||
965 | length_in_bytes = | ||
966 | SegmentSize; | ||
967 | CurDesc.DataBufferPtrLow = | ||
968 | pci_map_single(pAdapter-> | ||
969 | pdev, | ||
970 | pPacket-> | ||
971 | data, | ||
972 | SegmentSize, | ||
973 | PCI_DMA_TODEVICE); | ||
974 | DBG_TX(et131x_dbginfo, | ||
975 | "pci_map_single() returns: 0x%08x\n", | ||
976 | CurDesc. | ||
977 | DataBufferPtrLow); | ||
978 | } else { | ||
979 | DBG_TX(et131x_dbginfo, | ||
980 | "Got fragment of length %d, fragIndex: %d\n", | ||
981 | pPacket->len - | ||
982 | pPacket->data_len, | ||
983 | fragIndex); | ||
984 | DBG_TX(et131x_dbginfo, | ||
985 | "Leftover Size: %d\n", | ||
986 | (pPacket->len - | ||
987 | pPacket->data_len - | ||
988 | SegmentSize)); | ||
989 | |||
990 | CurDesc.word2.bits. | ||
991 | length_in_bytes = | ||
992 | ((pPacket->len - | ||
993 | pPacket->data_len) - | ||
994 | SegmentSize); | ||
995 | CurDesc.DataBufferPtrLow = | ||
996 | pci_map_single(pAdapter-> | ||
997 | pdev, | ||
998 | (pPacket-> | ||
999 | data + | ||
1000 | SegmentSize), | ||
1001 | (pPacket-> | ||
1002 | len - | ||
1003 | pPacket-> | ||
1004 | data_len - | ||
1005 | SegmentSize), | ||
1006 | PCI_DMA_TODEVICE); | ||
1007 | DBG_TX(et131x_dbginfo, | ||
1008 | "pci_map_single() returns: 0x%08x\n", | ||
1009 | CurDesc. | ||
1010 | DataBufferPtrLow); | ||
1011 | } | ||
1012 | } else { | ||
1013 | DBG_TX(et131x_dbginfo, | ||
1014 | "Split first element: NO\n"); | ||
1015 | |||
1016 | CurDesc.word2.bits.length_in_bytes = | ||
1017 | pPacket->len - pPacket->data_len; | ||
1018 | |||
1019 | CurDesc.DataBufferPtrLow = | ||
1020 | pci_map_single(pAdapter->pdev, | ||
1021 | pPacket->data, | ||
1022 | (pPacket->len - | ||
1023 | pPacket->data_len), | ||
1024 | PCI_DMA_TODEVICE); | ||
1025 | DBG_TX(et131x_dbginfo, | ||
1026 | "pci_map_single() returns: 0x%08x\n", | ||
1027 | CurDesc.DataBufferPtrLow); | ||
1028 | } | ||
1029 | } else { | ||
1030 | |||
1031 | CurDesc.word2.bits.length_in_bytes = | ||
1032 | pFragList[fragIndex - 1].size; | ||
1033 | CurDesc.DataBufferPtrLow = | ||
1034 | pci_map_page(pAdapter->pdev, | ||
1035 | pFragList[fragIndex - 1].page, | ||
1036 | pFragList[fragIndex - | ||
1037 | 1].page_offset, | ||
1038 | pFragList[fragIndex - 1].size, | ||
1039 | PCI_DMA_TODEVICE); | ||
1040 | DBG_TX(et131x_dbginfo, | ||
1041 | "pci_map_page() returns: 0x%08x\n", | ||
1042 | CurDesc.DataBufferPtrLow); | ||
1043 | } | ||
1044 | |||
1045 | if (loopIndex == 0) { | ||
1046 | /* This is the first descriptor of the packet | ||
1047 | * | ||
1048 | * Set the "f" bit to indicate this is the | ||
1049 | * first descriptor in the packet. | ||
1050 | */ | ||
1051 | DBG_TX(et131x_dbginfo, | ||
1052 | "This is our FIRST descriptor\n"); | ||
1053 | CurDesc.word3.bits.f = 1; | ||
1054 | |||
1055 | pMpTcb->WrIndexStart = | ||
1056 | pAdapter->TxRing.txDmaReadyToSend; | ||
1057 | } | ||
1058 | |||
1059 | if ((loopIndex == (loopEnd - 1)) && | ||
1060 | (pAdapter->uiDuplexMode || | ||
1061 | (pMpTcb->PacketLength >= NIC_MIN_PACKET_SIZE))) { | ||
1062 | /* This is the Last descriptor of the packet */ | ||
1063 | DBG_TX(et131x_dbginfo, | ||
1064 | "THIS is our LAST descriptor\n"); | ||
1065 | |||
1066 | if (pAdapter->uiLinkSpeed == | ||
1067 | TRUEPHY_SPEED_1000MBPS) { | ||
1068 | if (++pAdapter->TxRing. | ||
1069 | TxPacketsSinceLastinterrupt >= | ||
1070 | pAdapter->RegistryTxNumBuffers) { | ||
1071 | CurDesc.word3.value = 0x5; | ||
1072 | pAdapter->TxRing. | ||
1073 | TxPacketsSinceLastinterrupt | ||
1074 | = 0; | ||
1075 | } else { | ||
1076 | CurDesc.word3.value = 0x1; | ||
1077 | } | ||
1078 | } else { | ||
1079 | CurDesc.word3.value = 0x5; | ||
1080 | } | ||
1081 | |||
1082 | /* Following index will be used during freeing | ||
1083 | * of packet | ||
1084 | */ | ||
1085 | pMpTcb->WrIndex = | ||
1086 | pAdapter->TxRing.txDmaReadyToSend; | ||
1087 | pMpTcb->PacketStaleCount = 0; | ||
1088 | } | ||
1089 | |||
1090 | /* Copy the descriptor (filled above) into the | ||
1091 | * descriptor ring at the next free entry. Advance | ||
1092 | * the "next free entry" variable | ||
1093 | */ | ||
1094 | memcpy(pAdapter->TxRing.pTxDescRingVa + | ||
1095 | pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, | ||
1096 | &CurDesc, sizeof(TX_DESC_ENTRY_t)); | ||
1097 | |||
1098 | CurDescPostCopy = | ||
1099 | pAdapter->TxRing.pTxDescRingVa + | ||
1100 | pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; | ||
1101 | |||
1102 | DBG_TX(et131x_dbginfo, | ||
1103 | "CURRENT DESCRIPTOR\n" | ||
1104 | "\tAddress : 0x%p\n" | ||
1105 | "\tDataBufferPtrHigh : 0x%08x\n" | ||
1106 | "\tDataBufferPtrLow : 0x%08x\n" | ||
1107 | "\tword2 : 0x%08x\n" | ||
1108 | "\tword3 : 0x%08x\n", | ||
1109 | CurDescPostCopy, | ||
1110 | CurDescPostCopy->DataBufferPtrHigh, | ||
1111 | CurDescPostCopy->DataBufferPtrLow, | ||
1112 | CurDescPostCopy->word2.value, | ||
1113 | CurDescPostCopy->word3.value); | ||
1114 | |||
1115 | if (++pAdapter->TxRing.txDmaReadyToSend.bits.serv_req >= | ||
1116 | NUM_DESC_PER_RING_TX) { | ||
1117 | if (pAdapter->TxRing.txDmaReadyToSend.bits. | ||
1118 | serv_req_wrap) { | ||
1119 | pAdapter->TxRing.txDmaReadyToSend. | ||
1120 | value = 0; | ||
1121 | } else { | ||
1122 | pAdapter->TxRing.txDmaReadyToSend. | ||
1123 | value = 0x400; | ||
1124 | } | ||
1125 | } | ||
1126 | } | ||
1127 | } | ||
1128 | |||
1129 | if (pAdapter->uiDuplexMode == 0 && | ||
1130 | pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE) { | ||
1131 | // NOTE - Same 32/64-bit issue as above... | ||
1132 | CurDesc.DataBufferPtrHigh = 0x0; | ||
1133 | CurDesc.DataBufferPtrLow = pAdapter->TxRing.pTxDummyBlkPa; | ||
1134 | CurDesc.word2.value = 0; | ||
1135 | |||
1136 | if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) { | ||
1137 | if (++pAdapter->TxRing.TxPacketsSinceLastinterrupt >= | ||
1138 | pAdapter->RegistryTxNumBuffers) { | ||
1139 | CurDesc.word3.value = 0x5; | ||
1140 | pAdapter->TxRing.TxPacketsSinceLastinterrupt = | ||
1141 | 0; | ||
1142 | } else { | ||
1143 | CurDesc.word3.value = 0x1; | ||
1144 | } | ||
1145 | } else { | ||
1146 | CurDesc.word3.value = 0x5; | ||
1147 | } | ||
1148 | |||
1149 | CurDesc.word2.bits.length_in_bytes = | ||
1150 | NIC_MIN_PACKET_SIZE - pMpTcb->PacketLength; | ||
1151 | |||
1152 | pMpTcb->WrIndex = pAdapter->TxRing.txDmaReadyToSend; | ||
1153 | |||
1154 | memcpy(pAdapter->TxRing.pTxDescRingVa + | ||
1155 | pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, | ||
1156 | &CurDesc, sizeof(TX_DESC_ENTRY_t)); | ||
1157 | |||
1158 | CurDescPostCopy = | ||
1159 | pAdapter->TxRing.pTxDescRingVa + | ||
1160 | pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; | ||
1161 | |||
1162 | DBG_TX(et131x_dbginfo, | ||
1163 | "CURRENT DESCRIPTOR\n" | ||
1164 | "\tAddress : 0x%p\n" | ||
1165 | "\tDataBufferPtrHigh : 0x%08x\n" | ||
1166 | "\tDataBufferPtrLow : 0x%08x\n" | ||
1167 | "\tword2 : 0x%08x\n" | ||
1168 | "\tword3 : 0x%08x\n", | ||
1169 | CurDescPostCopy, | ||
1170 | CurDescPostCopy->DataBufferPtrHigh, | ||
1171 | CurDescPostCopy->DataBufferPtrLow, | ||
1172 | CurDescPostCopy->word2.value, | ||
1173 | CurDescPostCopy->word3.value); | ||
1174 | |||
1175 | if (++pAdapter->TxRing.txDmaReadyToSend.bits.serv_req >= | ||
1176 | NUM_DESC_PER_RING_TX) { | ||
1177 | if (pAdapter->TxRing.txDmaReadyToSend.bits. | ||
1178 | serv_req_wrap) { | ||
1179 | pAdapter->TxRing.txDmaReadyToSend.value = 0; | ||
1180 | } else { | ||
1181 | pAdapter->TxRing.txDmaReadyToSend.value = 0x400; | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | DBG_TX(et131x_dbginfo, "Padding descriptor %d by %d bytes\n", | ||
1186 | //pAdapter->TxRing.txDmaReadyToSend.value, | ||
1187 | pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, | ||
1188 | NIC_MIN_PACKET_SIZE - pMpTcb->PacketLength); | ||
1189 | } | ||
1190 | |||
1191 | spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags2); | ||
1192 | |||
1193 | if (pAdapter->TxRing.CurrSendTail) { | ||
1194 | pAdapter->TxRing.CurrSendTail->Next = pMpTcb; | ||
1195 | } else { | ||
1196 | pAdapter->TxRing.CurrSendHead = pMpTcb; | ||
1197 | } | ||
1198 | |||
1199 | pAdapter->TxRing.CurrSendTail = pMpTcb; | ||
1200 | |||
1201 | DBG_ASSERT(pMpTcb->Next == NULL); | ||
1202 | |||
1203 | pAdapter->TxRing.nBusySend++; | ||
1204 | |||
1205 | spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags2); | ||
1206 | |||
1207 | /* Write the new write pointer back to the device. */ | ||
1208 | writel(pAdapter->TxRing.txDmaReadyToSend.value, | ||
1209 | &pAdapter->CSRAddress->txdma.service_request.value); | ||
1210 | |||
1211 | #ifdef CONFIG_ET131X_DEBUG | ||
1212 | DumpDeviceBlock(DBG_TX_ON, pAdapter, 1); | ||
1213 | #endif | ||
1214 | |||
1215 | /* For Gig only, we use Tx Interrupt coalescing. Enable the software | ||
1216 | * timer to wake us up if this packet isn't followed by N more. | ||
1217 | */ | ||
1218 | if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) { | ||
1219 | writel(pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO, | ||
1220 | &pAdapter->CSRAddress->global.watchdog_timer); | ||
1221 | } | ||
1222 | |||
1223 | spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags1); | ||
1224 | |||
1225 | DBG_TX_LEAVE(et131x_dbginfo); | ||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1229 | #endif | ||
1230 | |||
1231 | /** | ||
1232 | * et131x_free_send_packet - Recycle a MP_TCB, complete the packet if necessary | ||
1233 | * @pAdapter: pointer to our adapter | ||
1234 | * @pMpTcb: pointer to MP_TCB | ||
1235 | * | ||
1236 | * Assumption - Send spinlock has been acquired | ||
1237 | */ | ||
1238 | __inline void et131x_free_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb) | ||
1239 | { | ||
1240 | unsigned long lockflags; | ||
1241 | TX_DESC_ENTRY_t *desc = NULL; | ||
1242 | struct net_device_stats *stats = &pAdapter->net_stats; | ||
1243 | |||
1244 | if (MP_TEST_FLAG(pMpTcb, fMP_DEST_BROAD)) { | ||
1245 | atomic_inc(&pAdapter->Stats.brdcstxmt); | ||
1246 | } else if (MP_TEST_FLAG(pMpTcb, fMP_DEST_MULTI)) { | ||
1247 | atomic_inc(&pAdapter->Stats.multixmt); | ||
1248 | } else { | ||
1249 | atomic_inc(&pAdapter->Stats.unixmt); | ||
1250 | } | ||
1251 | |||
1252 | if (pMpTcb->Packet) { | ||
1253 | stats->tx_bytes += pMpTcb->Packet->len; | ||
1254 | |||
1255 | /* Iterate through the TX descriptors on the ring | ||
1256 | * corresponding to this packet and umap the fragments | ||
1257 | * they point to | ||
1258 | */ | ||
1259 | DBG_TX(et131x_dbginfo, | ||
1260 | "Unmap descriptors Here\n" | ||
1261 | "TCB : 0x%p\n" | ||
1262 | "TCB Next : 0x%p\n" | ||
1263 | "TCB PacketLength : %d\n" | ||
1264 | "TCB WrIndex.value : 0x%08x\n" | ||
1265 | "TCB WrIndex.bits.val : %d\n" | ||
1266 | "TCB WrIndex.value : 0x%08x\n" | ||
1267 | "TCB WrIndex.bits.val : %d\n", | ||
1268 | pMpTcb, | ||
1269 | pMpTcb->Next, | ||
1270 | pMpTcb->PacketLength, | ||
1271 | pMpTcb->WrIndexStart.value, | ||
1272 | pMpTcb->WrIndexStart.bits.val, | ||
1273 | pMpTcb->WrIndex.value, | ||
1274 | pMpTcb->WrIndex.bits.val); | ||
1275 | |||
1276 | do { | ||
1277 | desc = | ||
1278 | (TX_DESC_ENTRY_t *) (pAdapter->TxRing. | ||
1279 | pTxDescRingVa + | ||
1280 | pMpTcb->WrIndexStart.bits.val); | ||
1281 | |||
1282 | DBG_TX(et131x_dbginfo, | ||
1283 | "CURRENT DESCRIPTOR\n" | ||
1284 | "\tAddress : 0x%p\n" | ||
1285 | "\tDataBufferPtrHigh : 0x%08x\n" | ||
1286 | "\tDataBufferPtrLow : 0x%08x\n" | ||
1287 | "\tword2 : 0x%08x\n" | ||
1288 | "\tword3 : 0x%08x\n", | ||
1289 | desc, | ||
1290 | desc->DataBufferPtrHigh, | ||
1291 | desc->DataBufferPtrLow, | ||
1292 | desc->word2.value, | ||
1293 | desc->word3.value); | ||
1294 | |||
1295 | pci_unmap_single(pAdapter->pdev, | ||
1296 | desc->DataBufferPtrLow, | ||
1297 | desc->word2.value, PCI_DMA_TODEVICE); | ||
1298 | |||
1299 | if (++pMpTcb->WrIndexStart.bits.val >= | ||
1300 | NUM_DESC_PER_RING_TX) { | ||
1301 | if (pMpTcb->WrIndexStart.bits.wrap) { | ||
1302 | pMpTcb->WrIndexStart.value = 0; | ||
1303 | } else { | ||
1304 | pMpTcb->WrIndexStart.value = 0x400; | ||
1305 | } | ||
1306 | } | ||
1307 | } | ||
1308 | while (desc != (pAdapter->TxRing.pTxDescRingVa + | ||
1309 | pMpTcb->WrIndex.bits.val)); | ||
1310 | |||
1311 | DBG_TX(et131x_dbginfo, | ||
1312 | "Free Packet (SKB) : 0x%p\n", pMpTcb->Packet); | ||
1313 | |||
1314 | dev_kfree_skb_any(pMpTcb->Packet); | ||
1315 | } | ||
1316 | |||
1317 | memset(pMpTcb, 0, sizeof(MP_TCB)); | ||
1318 | |||
1319 | /* Add the TCB to the Ready Q */ | ||
1320 | spin_lock_irqsave(&pAdapter->TCBReadyQLock, lockflags); | ||
1321 | |||
1322 | pAdapter->Stats.opackets++; | ||
1323 | |||
1324 | if (pAdapter->TxRing.TCBReadyQueueTail) { | ||
1325 | pAdapter->TxRing.TCBReadyQueueTail->Next = pMpTcb; | ||
1326 | } else { | ||
1327 | /* Apparently ready Q is empty. */ | ||
1328 | pAdapter->TxRing.TCBReadyQueueHead = pMpTcb; | ||
1329 | } | ||
1330 | |||
1331 | pAdapter->TxRing.TCBReadyQueueTail = pMpTcb; | ||
1332 | |||
1333 | spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags); | ||
1334 | |||
1335 | DBG_ASSERT(pAdapter->TxRing.nBusySend >= 0); | ||
1336 | } | ||
1337 | |||
1338 | /** | ||
1339 | * et131x_free_busy_send_packets - Free and complete the stopped active sends | ||
1340 | * @pAdapter: pointer to our adapter | ||
1341 | * | ||
1342 | * Assumption - Send spinlock has been acquired | ||
1343 | */ | ||
1344 | void et131x_free_busy_send_packets(struct et131x_adapter *pAdapter) | ||
1345 | { | ||
1346 | PMP_TCB pMpTcb; | ||
1347 | struct list_head *pEntry; | ||
1348 | struct sk_buff *pPacket = NULL; | ||
1349 | unsigned long lockflags; | ||
1350 | uint32_t FreeCounter = 0; | ||
1351 | |||
1352 | DBG_ENTER(et131x_dbginfo); | ||
1353 | |||
1354 | while (!list_empty(&pAdapter->TxRing.SendWaitQueue)) { | ||
1355 | spin_lock_irqsave(&pAdapter->SendWaitLock, lockflags); | ||
1356 | |||
1357 | pAdapter->TxRing.nWaitSend--; | ||
1358 | spin_unlock_irqrestore(&pAdapter->SendWaitLock, lockflags); | ||
1359 | |||
1360 | pEntry = pAdapter->TxRing.SendWaitQueue.next; | ||
1361 | |||
1362 | pPacket = NULL; | ||
1363 | } | ||
1364 | |||
1365 | pAdapter->TxRing.nWaitSend = 0; | ||
1366 | |||
1367 | /* Any packets being sent? Check the first TCB on the send list */ | ||
1368 | spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags); | ||
1369 | |||
1370 | pMpTcb = pAdapter->TxRing.CurrSendHead; | ||
1371 | |||
1372 | while ((pMpTcb != NULL) && (FreeCounter < NUM_TCB)) { | ||
1373 | PMP_TCB pNext = pMpTcb->Next; | ||
1374 | |||
1375 | pAdapter->TxRing.CurrSendHead = pNext; | ||
1376 | |||
1377 | if (pNext == NULL) { | ||
1378 | pAdapter->TxRing.CurrSendTail = NULL; | ||
1379 | } | ||
1380 | |||
1381 | pAdapter->TxRing.nBusySend--; | ||
1382 | |||
1383 | spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags); | ||
1384 | |||
1385 | DBG_VERBOSE(et131x_dbginfo, "pMpTcb = 0x%p\n", pMpTcb); | ||
1386 | |||
1387 | FreeCounter++; | ||
1388 | MP_FREE_SEND_PACKET_FUN(pAdapter, pMpTcb); | ||
1389 | |||
1390 | spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags); | ||
1391 | |||
1392 | pMpTcb = pAdapter->TxRing.CurrSendHead; | ||
1393 | } | ||
1394 | |||
1395 | if (FreeCounter == NUM_TCB) { | ||
1396 | DBG_ERROR(et131x_dbginfo, | ||
1397 | "MpFreeBusySendPackets exitted loop for a bad reason\n"); | ||
1398 | BUG(); | ||
1399 | } | ||
1400 | |||
1401 | spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags); | ||
1402 | |||
1403 | pAdapter->TxRing.nBusySend = 0; | ||
1404 | |||
1405 | DBG_LEAVE(et131x_dbginfo); | ||
1406 | } | ||
1407 | |||
1408 | /** | ||
1409 | * et131x_handle_send_interrupt - Interrupt handler for sending processing | ||
1410 | * @pAdapter: pointer to our adapter | ||
1411 | * | ||
1412 | * Re-claim the send resources, complete sends and get more to send from | ||
1413 | * the send wait queue. | ||
1414 | * | ||
1415 | * Assumption - Send spinlock has been acquired | ||
1416 | */ | ||
1417 | void et131x_handle_send_interrupt(struct et131x_adapter *pAdapter) | ||
1418 | { | ||
1419 | DBG_TX_ENTER(et131x_dbginfo); | ||
1420 | |||
1421 | /* Mark as completed any packets which have been sent by the device. */ | ||
1422 | et131x_update_tcb_list(pAdapter); | ||
1423 | |||
1424 | /* If we queued any transmits because we didn't have any TCBs earlier, | ||
1425 | * dequeue and send those packets now, as long as we have free TCBs. | ||
1426 | */ | ||
1427 | et131x_check_send_wait_list(pAdapter); | ||
1428 | |||
1429 | DBG_TX_LEAVE(et131x_dbginfo); | ||
1430 | } | ||
1431 | |||
1432 | /** | ||
1433 | * et131x_update_tcb_list - Helper routine for Send Interrupt handler | ||
1434 | * @pAdapter: pointer to our adapter | ||
1435 | * | ||
1436 | * Re-claims the send resources and completes sends. Can also be called as | ||
1437 | * part of the NIC send routine when the "ServiceComplete" indication has | ||
1438 | * wrapped. | ||
1439 | */ | ||
1440 | static void et131x_update_tcb_list(struct et131x_adapter *pAdapter) | ||
1441 | { | ||
1442 | unsigned long lockflags; | ||
1443 | DMA10W_t ServiceComplete; | ||
1444 | PMP_TCB pMpTcb; | ||
1445 | |||
1446 | ServiceComplete.value = | ||
1447 | readl(&pAdapter->CSRAddress->txdma.NewServiceComplete.value); | ||
1448 | |||
1449 | /* Has the ring wrapped? Process any descriptors that do not have | ||
1450 | * the same "wrap" indicator as the current completion indicator | ||
1451 | */ | ||
1452 | spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags); | ||
1453 | |||
1454 | pMpTcb = pAdapter->TxRing.CurrSendHead; | ||
1455 | while (pMpTcb && | ||
1456 | ServiceComplete.bits.wrap != pMpTcb->WrIndex.bits.wrap && | ||
1457 | ServiceComplete.bits.val < pMpTcb->WrIndex.bits.val) { | ||
1458 | pAdapter->TxRing.nBusySend--; | ||
1459 | pAdapter->TxRing.CurrSendHead = pMpTcb->Next; | ||
1460 | if (pMpTcb->Next == NULL) { | ||
1461 | pAdapter->TxRing.CurrSendTail = NULL; | ||
1462 | } | ||
1463 | |||
1464 | spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags); | ||
1465 | MP_FREE_SEND_PACKET_FUN(pAdapter, pMpTcb); | ||
1466 | spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags); | ||
1467 | |||
1468 | /* Goto the next packet */ | ||
1469 | pMpTcb = pAdapter->TxRing.CurrSendHead; | ||
1470 | } | ||
1471 | while (pMpTcb && | ||
1472 | ServiceComplete.bits.wrap == pMpTcb->WrIndex.bits.wrap && | ||
1473 | ServiceComplete.bits.val > pMpTcb->WrIndex.bits.val) { | ||
1474 | pAdapter->TxRing.nBusySend--; | ||
1475 | pAdapter->TxRing.CurrSendHead = pMpTcb->Next; | ||
1476 | if (pMpTcb->Next == NULL) { | ||
1477 | pAdapter->TxRing.CurrSendTail = NULL; | ||
1478 | } | ||
1479 | |||
1480 | spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags); | ||
1481 | MP_FREE_SEND_PACKET_FUN(pAdapter, pMpTcb); | ||
1482 | spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags); | ||
1483 | |||
1484 | /* Goto the next packet */ | ||
1485 | pMpTcb = pAdapter->TxRing.CurrSendHead; | ||
1486 | } | ||
1487 | |||
1488 | /* Wake up the queue when we hit a low-water mark */ | ||
1489 | if (pAdapter->TxRing.nBusySend <= (NUM_TCB / 3)) { | ||
1490 | netif_wake_queue(pAdapter->netdev); | ||
1491 | } | ||
1492 | |||
1493 | spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags); | ||
1494 | } | ||
1495 | |||
1496 | /** | ||
1497 | * et131x_check_send_wait_list - Helper routine for the interrupt handler | ||
1498 | * @pAdapter: pointer to our adapter | ||
1499 | * | ||
1500 | * Takes packets from the send wait queue and posts them to the device (if | ||
1501 | * room available). | ||
1502 | */ | ||
1503 | static void et131x_check_send_wait_list(struct et131x_adapter *pAdapter) | ||
1504 | { | ||
1505 | unsigned long lockflags; | ||
1506 | |||
1507 | spin_lock_irqsave(&pAdapter->SendWaitLock, lockflags); | ||
1508 | |||
1509 | while (!list_empty(&pAdapter->TxRing.SendWaitQueue) && | ||
1510 | MP_TCB_RESOURCES_AVAILABLE(pAdapter)) { | ||
1511 | struct list_head *pEntry; | ||
1512 | |||
1513 | DBG_VERBOSE(et131x_dbginfo, "Tx packets on the wait queue\n"); | ||
1514 | |||
1515 | pEntry = pAdapter->TxRing.SendWaitQueue.next; | ||
1516 | |||
1517 | pAdapter->TxRing.nWaitSend--; | ||
1518 | |||
1519 | DBG_WARNING(et131x_dbginfo, | ||
1520 | "MpHandleSendInterrupt - sent a queued pkt. Waiting %d\n", | ||
1521 | pAdapter->TxRing.nWaitSend); | ||
1522 | } | ||
1523 | |||
1524 | spin_unlock_irqrestore(&pAdapter->SendWaitLock, lockflags); | ||
1525 | } | ||
diff --git a/drivers/staging/et131x/et1310_tx.h b/drivers/staging/et131x/et1310_tx.h new file mode 100644 index 000000000000..2819c7843d21 --- /dev/null +++ b/drivers/staging/et131x/et1310_tx.h | |||
@@ -0,0 +1,242 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et1310_tx.h - Defines, structs, enums, prototypes, etc. pertaining to data | ||
12 | * transmission. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef __ET1310_TX_H__ | ||
60 | #define __ET1310_TX_H__ | ||
61 | |||
62 | |||
63 | /* Typedefs for Tx Descriptor Ring */ | ||
64 | |||
65 | /* | ||
66 | * TXDESC_WORD2_t structure holds part of the control bits in the Tx Descriptor | ||
67 | * ring for the ET-1310 | ||
68 | */ | ||
69 | typedef union _txdesc_word2_t { | ||
70 | u32 value; | ||
71 | struct { | ||
72 | #ifdef _BIT_FIELDS_HTOL | ||
73 | u32 vlan_prio:3; // bits 29-31(VLAN priority) | ||
74 | u32 vlan_cfi:1; // bit 28(cfi) | ||
75 | u32 vlan_tag:12; // bits 16-27(VLAN tag) | ||
76 | u32 length_in_bytes:16; // bits 0-15(packet length) | ||
77 | #else | ||
78 | u32 length_in_bytes:16; // bits 0-15(packet length) | ||
79 | u32 vlan_tag:12; // bits 16-27(VLAN tag) | ||
80 | u32 vlan_cfi:1; // bit 28(cfi) | ||
81 | u32 vlan_prio:3; // bits 29-31(VLAN priority) | ||
82 | #endif /* _BIT_FIELDS_HTOL */ | ||
83 | } bits; | ||
84 | } TXDESC_WORD2_t, *PTXDESC_WORD2_t; | ||
85 | |||
86 | /* | ||
87 | * TXDESC_WORD3_t structure holds part of the control bits in the Tx Descriptor | ||
88 | * ring for the ET-1310 | ||
89 | */ | ||
90 | typedef union _txdesc_word3_t { | ||
91 | u32 value; | ||
92 | struct { | ||
93 | #ifdef _BIT_FIELDS_HTOL | ||
94 | u32 unused:17; // bits 15-31 | ||
95 | u32 udpa:1; // bit 14(UDP checksum assist) | ||
96 | u32 tcpa:1; // bit 13(TCP checksum assist) | ||
97 | u32 ipa:1; // bit 12(IP checksum assist) | ||
98 | u32 vlan:1; // bit 11(append VLAN tag) | ||
99 | u32 hp:1; // bit 10(Packet is a Huge packet) | ||
100 | u32 pp:1; // bit 9(pad packet) | ||
101 | u32 mac:1; // bit 8(MAC override) | ||
102 | u32 crc:1; // bit 7(append CRC) | ||
103 | u32 e:1; // bit 6(Tx frame has error) | ||
104 | u32 pf:1; // bit 5(send pause frame) | ||
105 | u32 bp:1; // bit 4(Issue half-duplex backpressure (XON/XOFF) | ||
106 | u32 cw:1; // bit 3(Control word - no packet data) | ||
107 | u32 ir:1; // bit 2(interrupt the processor when this pkt sent) | ||
108 | u32 f:1; // bit 1(first packet in the sequence) | ||
109 | u32 l:1; // bit 0(last packet in the sequence) | ||
110 | #else | ||
111 | u32 l:1; // bit 0(last packet in the sequence) | ||
112 | u32 f:1; // bit 1(first packet in the sequence) | ||
113 | u32 ir:1; // bit 2(interrupt the processor when this pkt sent) | ||
114 | u32 cw:1; // bit 3(Control word - no packet data) | ||
115 | u32 bp:1; // bit 4(Issue half-duplex backpressure (XON/XOFF) | ||
116 | u32 pf:1; // bit 5(send pause frame) | ||
117 | u32 e:1; // bit 6(Tx frame has error) | ||
118 | u32 crc:1; // bit 7(append CRC) | ||
119 | u32 mac:1; // bit 8(MAC override) | ||
120 | u32 pp:1; // bit 9(pad packet) | ||
121 | u32 hp:1; // bit 10(Packet is a Huge packet) | ||
122 | u32 vlan:1; // bit 11(append VLAN tag) | ||
123 | u32 ipa:1; // bit 12(IP checksum assist) | ||
124 | u32 tcpa:1; // bit 13(TCP checksum assist) | ||
125 | u32 udpa:1; // bit 14(UDP checksum assist) | ||
126 | u32 unused:17; // bits 15-31 | ||
127 | #endif /* _BIT_FIELDS_HTOL */ | ||
128 | } bits; | ||
129 | } TXDESC_WORD3_t, *PTXDESC_WORD3_t; | ||
130 | |||
131 | /* TX_DESC_ENTRY_t is sructure representing each descriptor on the ring */ | ||
132 | typedef struct _tx_desc_entry_t { | ||
133 | u32 DataBufferPtrHigh; | ||
134 | u32 DataBufferPtrLow; | ||
135 | TXDESC_WORD2_t word2; // control words how to xmit the | ||
136 | TXDESC_WORD3_t word3; // data (detailed above) | ||
137 | } TX_DESC_ENTRY_t, *PTX_DESC_ENTRY_t; | ||
138 | |||
139 | |||
140 | /* Typedefs for Tx DMA engine status writeback */ | ||
141 | |||
142 | /* | ||
143 | * TX_STATUS_BLOCK_t is sructure representing the status of the Tx DMA engine | ||
144 | * it sits in free memory, and is pointed to by 0x101c / 0x1020 | ||
145 | */ | ||
146 | typedef union _tx_status_block_t { | ||
147 | u32 value; | ||
148 | struct { | ||
149 | #ifdef _BIT_FIELDS_HTOL | ||
150 | u32 unused:21; // bits 11-31 | ||
151 | u32 serv_cpl_wrap:1; // bit 10 | ||
152 | u32 serv_cpl:10; // bits 0-9 | ||
153 | #else | ||
154 | u32 serv_cpl:10; // bits 0-9 | ||
155 | u32 serv_cpl_wrap:1; // bit 10 | ||
156 | u32 unused:21; // bits 11-31 | ||
157 | #endif | ||
158 | } bits; | ||
159 | } TX_STATUS_BLOCK_t, *PTX_STATUS_BLOCK_t; | ||
160 | |||
161 | /* TCB (Transmit Control Block) */ | ||
162 | typedef struct _MP_TCB { | ||
163 | struct _MP_TCB *Next; | ||
164 | u32 Flags; | ||
165 | u32 Count; | ||
166 | u32 PacketStaleCount; | ||
167 | struct sk_buff *Packet; | ||
168 | u32 PacketLength; | ||
169 | DMA10W_t WrIndex; | ||
170 | DMA10W_t WrIndexStart; | ||
171 | } MP_TCB, *PMP_TCB; | ||
172 | |||
173 | /* Structure to hold the skb's in a list */ | ||
174 | typedef struct tx_skb_list_elem { | ||
175 | struct list_head skb_list_elem; | ||
176 | struct sk_buff *skb; | ||
177 | } TX_SKB_LIST_ELEM, *PTX_SKB_LIST_ELEM; | ||
178 | |||
179 | /* TX_RING_t is sructure representing our local reference(s) to the ring */ | ||
180 | typedef struct _tx_ring_t { | ||
181 | /* TCB (Transmit Control Block) memory and lists */ | ||
182 | PMP_TCB MpTcbMem; | ||
183 | |||
184 | /* List of TCBs that are ready to be used */ | ||
185 | PMP_TCB TCBReadyQueueHead; | ||
186 | PMP_TCB TCBReadyQueueTail; | ||
187 | |||
188 | /* list of TCBs that are currently being sent. NOTE that access to all | ||
189 | * three of these (including nBusySend) are controlled via the | ||
190 | * TCBSendQLock. This lock should be secured prior to incementing / | ||
191 | * decrementing nBusySend, or any queue manipulation on CurrSendHead / | ||
192 | * Tail | ||
193 | */ | ||
194 | PMP_TCB CurrSendHead; | ||
195 | PMP_TCB CurrSendTail; | ||
196 | int32_t nBusySend; | ||
197 | |||
198 | /* List of packets (not TCBs) that were queued for lack of resources */ | ||
199 | struct list_head SendWaitQueue; | ||
200 | int32_t nWaitSend; | ||
201 | |||
202 | /* The actual descriptor ring */ | ||
203 | PTX_DESC_ENTRY_t pTxDescRingVa; | ||
204 | dma_addr_t pTxDescRingPa; | ||
205 | uint64_t pTxDescRingAdjustedPa; | ||
206 | uint64_t TxDescOffset; | ||
207 | |||
208 | /* ReadyToSend indicates where we last wrote to in the descriptor ring. */ | ||
209 | DMA10W_t txDmaReadyToSend; | ||
210 | |||
211 | /* The location of the write-back status block */ | ||
212 | PTX_STATUS_BLOCK_t pTxStatusVa; | ||
213 | dma_addr_t pTxStatusPa; | ||
214 | |||
215 | /* A Block of zeroes used to pad packets that are less than 60 bytes */ | ||
216 | void *pTxDummyBlkVa; | ||
217 | dma_addr_t pTxDummyBlkPa; | ||
218 | |||
219 | TXMAC_ERR_t TxMacErr; | ||
220 | |||
221 | /* Variables to track the Tx interrupt coalescing features */ | ||
222 | int32_t TxPacketsSinceLastinterrupt; | ||
223 | } TX_RING_t, *PTX_RING_t; | ||
224 | |||
225 | /* Forward declaration of the frag-list for the following prototypes */ | ||
226 | typedef struct _MP_FRAG_LIST MP_FRAG_LIST, *PMP_FRAG_LIST; | ||
227 | |||
228 | /* Forward declaration of the private adapter structure */ | ||
229 | struct et131x_adapter; | ||
230 | |||
231 | /* PROTOTYPES for et1310_tx.c */ | ||
232 | int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter); | ||
233 | void et131x_tx_dma_memory_free(struct et131x_adapter *adapter); | ||
234 | void ConfigTxDmaRegs(struct et131x_adapter *pAdapter); | ||
235 | void et131x_init_send(struct et131x_adapter *adapter); | ||
236 | void et131x_tx_dma_disable(struct et131x_adapter *pAdapter); | ||
237 | void et131x_tx_dma_enable(struct et131x_adapter *pAdapter); | ||
238 | void et131x_handle_send_interrupt(struct et131x_adapter *pAdapter); | ||
239 | void et131x_free_busy_send_packets(struct et131x_adapter *pAdapter); | ||
240 | int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev); | ||
241 | |||
242 | #endif /* __ET1310_TX_H__ */ | ||
diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h new file mode 100644 index 000000000000..36e61a47ae27 --- /dev/null +++ b/drivers/staging/et131x/et131x_adapter.h | |||
@@ -0,0 +1,347 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_adapter.h - Header which includes the private adapter structure, along | ||
12 | * with related support structures, macros, definitions, etc. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef __ET131X_ADAPTER_H__ | ||
60 | #define __ET131X_ADAPTER_H__ | ||
61 | |||
62 | #include "et1310_address_map.h" | ||
63 | #include "et1310_tx.h" | ||
64 | #include "et1310_rx.h" | ||
65 | |||
66 | /* | ||
67 | * Do not change these values: if changed, then change also in respective | ||
68 | * TXdma and Rxdma engines | ||
69 | */ | ||
70 | #define NUM_DESC_PER_RING_TX 512 // TX Do not change these values | ||
71 | #define NUM_TCB 64 | ||
72 | |||
73 | /* | ||
74 | * These values are all superseded by registry entries to facilitate tuning. | ||
75 | * Once the desired performance has been achieved, the optimal registry values | ||
76 | * should be re-populated to these #defines: | ||
77 | */ | ||
78 | #define NUM_TRAFFIC_CLASSES 1 | ||
79 | |||
80 | /* | ||
81 | * There are three ways of counting errors - if there are more than X errors | ||
82 | * in Y packets (represented by the "SAMPLE" macros), if there are more than | ||
83 | * N errors in a S mSec time period (the "PERIOD" macros), or if there are | ||
84 | * consecutive packets with errors (CONSEC_ERRORED_THRESH). This last covers | ||
85 | * for "Bursty" errors, and the errored packets may well not be contiguous, | ||
86 | * but several errors where the packet counter has changed by less than a | ||
87 | * small amount will cause this count to increment. | ||
88 | */ | ||
89 | #define TX_PACKETS_IN_SAMPLE 10000 | ||
90 | #define TX_MAX_ERRORS_IN_SAMPLE 50 | ||
91 | |||
92 | #define TX_ERROR_PERIOD 1000 | ||
93 | #define TX_MAX_ERRORS_IN_PERIOD 10 | ||
94 | |||
95 | #define LINK_DETECTION_TIMER 5000 | ||
96 | |||
97 | #define TX_CONSEC_RANGE 5 | ||
98 | #define TX_CONSEC_ERRORED_THRESH 10 | ||
99 | |||
100 | #define LO_MARK_PERCENT_FOR_PSR 15 | ||
101 | #define LO_MARK_PERCENT_FOR_RX 15 | ||
102 | |||
103 | /* Macros for flag and ref count operations */ | ||
104 | #define MP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F)) | ||
105 | #define MP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F)) | ||
106 | #define MP_CLEAR_FLAGS(_M) ((_M)->Flags = 0) | ||
107 | #define MP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0) | ||
108 | #define MP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F)) | ||
109 | #define MP_IS_FLAG_CLEAR(_M, _F) (((_M)->Flags & (_F)) == 0) | ||
110 | |||
111 | #define MP_INC_RCV_REF(_A) atomic_inc(&(_A)->RcvRefCount) | ||
112 | #define MP_DEC_RCV_REF(_A) atomic_dec(&(_A)->RcvRefCount) | ||
113 | #define MP_GET_RCV_REF(_A) atomic_read(&(_A)->RcvRefCount) | ||
114 | |||
115 | /* Macros specific to the private adapter structure */ | ||
116 | #define MP_TCB_RESOURCES_AVAILABLE(_M) ((_M)->TxRing.nBusySend < NUM_TCB) | ||
117 | #define MP_TCB_RESOURCES_NOT_AVAILABLE(_M) ((_M)->TxRing.nBusySend >= NUM_TCB) | ||
118 | |||
119 | #define MP_SHOULD_FAIL_SEND(_M) ((_M)->Flags & fMP_ADAPTER_FAIL_SEND_MASK) | ||
120 | #define MP_IS_NOT_READY(_M) ((_M)->Flags & fMP_ADAPTER_NOT_READY_MASK) | ||
121 | #define MP_IS_READY(_M) !((_M)->Flags & fMP_ADAPTER_NOT_READY_MASK) | ||
122 | |||
123 | #define MP_HAS_CABLE(_M) !((_M)->Flags & fMP_ADAPTER_NO_CABLE) | ||
124 | #define MP_LINK_DETECTED(_M) !((_M)->Flags & fMP_ADAPTER_LINK_DETECTION) | ||
125 | |||
126 | /* Counters for error rate monitoring */ | ||
127 | typedef struct _MP_ERR_COUNTERS { | ||
128 | u32 PktCountTxPackets; | ||
129 | u32 PktCountTxErrors; | ||
130 | u32 TimerBasedTxErrors; | ||
131 | u32 PktCountLastError; | ||
132 | u32 ErredConsecPackets; | ||
133 | } MP_ERR_COUNTERS, *PMP_ERR_COUNTERS; | ||
134 | |||
135 | /* RFD (Receive Frame Descriptor) */ | ||
136 | typedef struct _MP_RFD { | ||
137 | struct list_head list_node; | ||
138 | struct sk_buff *Packet; | ||
139 | u32 PacketSize; // total size of receive frame | ||
140 | u16 iBufferIndex; | ||
141 | u8 iRingIndex; | ||
142 | } MP_RFD, *PMP_RFD; | ||
143 | |||
144 | /* Enum for Flow Control */ | ||
145 | typedef enum _eflow_control_t { | ||
146 | Both = 0, | ||
147 | TxOnly = 1, | ||
148 | RxOnly = 2, | ||
149 | None = 3 | ||
150 | } eFLOW_CONTROL_t, *PeFLOW_CONTROL_t; | ||
151 | |||
152 | /* Struct to define some device statistics */ | ||
153 | typedef struct _ce_stats_t { | ||
154 | /* Link Input/Output stats */ | ||
155 | uint64_t ipackets; // # of in packets | ||
156 | uint64_t opackets; // # of out packets | ||
157 | |||
158 | /* MIB II variables | ||
159 | * | ||
160 | * NOTE: atomic_t types are only guaranteed to store 24-bits; if we | ||
161 | * MUST have 32, then we'll need another way to perform atomic | ||
162 | * operations | ||
163 | */ | ||
164 | u32 unircv; // # multicast packets received | ||
165 | atomic_t unixmt; // # multicast packets for Tx | ||
166 | u32 multircv; // # multicast packets received | ||
167 | atomic_t multixmt; // # multicast packets for Tx | ||
168 | u32 brdcstrcv; // # broadcast packets received | ||
169 | atomic_t brdcstxmt; // # broadcast packets for Tx | ||
170 | u32 norcvbuf; // # Rx packets discarded | ||
171 | u32 noxmtbuf; // # Tx packets discarded | ||
172 | |||
173 | /* Transciever state informations. */ | ||
174 | u8 xcvr_addr; | ||
175 | u32 xcvr_id; | ||
176 | |||
177 | /* Tx Statistics. */ | ||
178 | u32 tx_uflo; // Tx Underruns | ||
179 | |||
180 | u32 collisions; | ||
181 | u32 excessive_collisions; | ||
182 | u32 first_collision; | ||
183 | u32 late_collisions; | ||
184 | u32 max_pkt_error; | ||
185 | u32 tx_deferred; | ||
186 | |||
187 | /* Rx Statistics. */ | ||
188 | u32 rx_ov_flow; // Rx Over Flow | ||
189 | |||
190 | u32 length_err; | ||
191 | u32 alignment_err; | ||
192 | u32 crc_err; | ||
193 | u32 code_violations; | ||
194 | u32 other_errors; | ||
195 | |||
196 | #ifdef CONFIG_ET131X_DEBUG | ||
197 | u32 UnhandledInterruptsPerSec; | ||
198 | u32 RxDmaInterruptsPerSec; | ||
199 | u32 TxDmaInterruptsPerSec; | ||
200 | u32 WatchDogInterruptsPerSec; | ||
201 | #endif /* CONFIG_ET131X_DEBUG */ | ||
202 | |||
203 | u32 SynchrounousIterations; | ||
204 | INTERRUPT_t InterruptStatus; | ||
205 | } CE_STATS_t, *PCE_STATS_t; | ||
206 | |||
207 | /* The private adapter structure */ | ||
208 | struct et131x_adapter { | ||
209 | struct net_device *netdev; | ||
210 | struct pci_dev *pdev; | ||
211 | |||
212 | struct work_struct task; | ||
213 | |||
214 | /* Flags that indicate current state of the adapter */ | ||
215 | u32 Flags; | ||
216 | u32 HwErrCount; | ||
217 | |||
218 | /* Configuration */ | ||
219 | u8 PermanentAddress[ETH_ALEN]; | ||
220 | u8 CurrentAddress[ETH_ALEN]; | ||
221 | bool bOverrideAddress; | ||
222 | bool bEepromPresent; | ||
223 | u8 eepromData[2]; | ||
224 | |||
225 | /* Spinlocks */ | ||
226 | spinlock_t Lock; | ||
227 | |||
228 | spinlock_t TCBSendQLock; | ||
229 | spinlock_t TCBReadyQLock; | ||
230 | spinlock_t SendHWLock; | ||
231 | spinlock_t SendWaitLock; | ||
232 | |||
233 | spinlock_t RcvLock; | ||
234 | spinlock_t RcvPendLock; | ||
235 | spinlock_t FbrLock; | ||
236 | |||
237 | spinlock_t PHYLock; | ||
238 | |||
239 | /* Packet Filter and look ahead size */ | ||
240 | u32 PacketFilter; | ||
241 | u32 ulLookAhead; | ||
242 | u32 uiLinkSpeed; | ||
243 | u32 uiDuplexMode; | ||
244 | u32 uiAutoNegStatus; | ||
245 | u8 ucLinkStatus; | ||
246 | |||
247 | /* multicast list */ | ||
248 | u32 MCAddressCount; | ||
249 | u8 MCList[NIC_MAX_MCAST_LIST][ETH_ALEN]; | ||
250 | |||
251 | /* MAC test */ | ||
252 | TXMAC_TXTEST_t TxMacTest; | ||
253 | |||
254 | /* Pointer to the device's PCI register space */ | ||
255 | ADDRESS_MAP_t __iomem *CSRAddress; | ||
256 | |||
257 | /* PCI config space info, for debug purposes only. */ | ||
258 | u8 RevisionID; | ||
259 | u16 VendorID; | ||
260 | u16 DeviceID; | ||
261 | u16 SubVendorID; | ||
262 | u16 SubSystemID; | ||
263 | u32 CacheFillSize; | ||
264 | u16 PciXDevCtl; | ||
265 | u8 pci_lat_timer; | ||
266 | u8 pci_hdr_type; | ||
267 | u8 pci_bist; | ||
268 | u32 pci_cfg_state[64 / sizeof(u32)]; | ||
269 | |||
270 | /* Registry parameters */ | ||
271 | u8 SpeedDuplex; // speed/duplex | ||
272 | eFLOW_CONTROL_t RegistryFlowControl; // for 802.3x flow control | ||
273 | u8 RegistryWOLMatch; // Enable WOL pattern-matching | ||
274 | u8 RegistryWOLLink; // Link state change is independant | ||
275 | u8 RegistryPhyComa; // Phy Coma mode enable/disable | ||
276 | |||
277 | u32 RegistryRxMemEnd; // Size of internal rx memory | ||
278 | u8 RegistryMACStat; // If set, read MACSTAT, else don't | ||
279 | u32 RegistryVlanTag; // 802.1q Vlan TAG | ||
280 | u32 RegistryJumboPacket; // Max supported ethernet packet size | ||
281 | |||
282 | u32 RegistryTxNumBuffers; | ||
283 | u32 RegistryTxTimeInterval; | ||
284 | |||
285 | u32 RegistryRxNumBuffers; | ||
286 | u32 RegistryRxTimeInterval; | ||
287 | |||
288 | /* Validation helpers */ | ||
289 | u8 RegistryPMWOL; | ||
290 | u8 RegistryNMIDisable; | ||
291 | u32 RegistryDMACache; | ||
292 | u32 RegistrySCGain; | ||
293 | u8 RegistryPhyLoopbk; // Enable Phy loopback | ||
294 | |||
295 | /* Derived from the registry: */ | ||
296 | u8 AiForceDpx; // duplex setting | ||
297 | u16 AiForceSpeed; // 'Speed', user over-ride of line speed | ||
298 | eFLOW_CONTROL_t FlowControl; // flow control validated by the far-end | ||
299 | enum { | ||
300 | NETIF_STATUS_INVALID = 0, | ||
301 | NETIF_STATUS_MEDIA_CONNECT, | ||
302 | NETIF_STATUS_MEDIA_DISCONNECT, | ||
303 | NETIF_STATUS_MAX | ||
304 | } MediaState; | ||
305 | u8 DriverNoPhyAccess; | ||
306 | |||
307 | /* Minimize init-time */ | ||
308 | bool bQueryPending; | ||
309 | bool bSetPending; | ||
310 | bool bResetPending; | ||
311 | struct timer_list ErrorTimer; | ||
312 | bool bLinkTimerActive; | ||
313 | MP_POWER_MGMT PoMgmt; | ||
314 | INTERRUPT_t CachedMaskValue; | ||
315 | |||
316 | atomic_t RcvRefCount; // Num packets not yet returned | ||
317 | |||
318 | /* Xcvr status at last poll */ | ||
319 | MI_BMSR_t Bmsr; | ||
320 | |||
321 | /* Tx Memory Variables */ | ||
322 | TX_RING_t TxRing; | ||
323 | |||
324 | /* Rx Memory Variables */ | ||
325 | RX_RING_t RxRing; | ||
326 | |||
327 | /* ET1310 register Access */ | ||
328 | JAGCORE_ACCESS_REGS JagCoreRegs; | ||
329 | PCI_CFG_SPACE_REGS PciCfgRegs; | ||
330 | |||
331 | /* Loopback specifics */ | ||
332 | u8 ReplicaPhyLoopbk; // Replica Enable | ||
333 | u8 ReplicaPhyLoopbkPF; // Replica Enable Pass/Fail | ||
334 | |||
335 | /* Stats */ | ||
336 | CE_STATS_t Stats; | ||
337 | |||
338 | struct net_device_stats net_stats; | ||
339 | struct net_device_stats net_stats_prev; | ||
340 | }; | ||
341 | |||
342 | #define MPSendPacketsHandler MPSendPackets | ||
343 | #define MP_FREE_SEND_PACKET_FUN(Adapter, pMpTcb) \ | ||
344 | et131x_free_send_packet(Adapter, pMpTcb) | ||
345 | #define MpSendPacketFun(Adapter, Packet) MpSendPacket(Adapter, Packet) | ||
346 | |||
347 | #endif /* __ET131X_ADAPTER_H__ */ | ||
diff --git a/drivers/staging/et131x/et131x_config.c b/drivers/staging/et131x/et131x_config.c new file mode 100644 index 000000000000..0adbaa6ca078 --- /dev/null +++ b/drivers/staging/et131x/et131x_config.c | |||
@@ -0,0 +1,325 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_config.c - Handles parsing of configuration data during | ||
12 | * initialization. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "et131x_version.h" | ||
60 | #include "et131x_debug.h" | ||
61 | #include "et131x_defs.h" | ||
62 | |||
63 | #include <linux/init.h> | ||
64 | #include <linux/module.h> | ||
65 | #include <linux/types.h> | ||
66 | #include <linux/kernel.h> | ||
67 | |||
68 | #include <linux/sched.h> | ||
69 | #include <linux/ptrace.h> | ||
70 | #include <linux/slab.h> | ||
71 | #include <linux/ctype.h> | ||
72 | #include <linux/string.h> | ||
73 | #include <linux/timer.h> | ||
74 | #include <linux/interrupt.h> | ||
75 | #include <linux/in.h> | ||
76 | #include <linux/delay.h> | ||
77 | #include <asm/io.h> | ||
78 | #include <asm/system.h> | ||
79 | #include <asm/bitops.h> | ||
80 | |||
81 | #include <linux/netdevice.h> | ||
82 | #include <linux/etherdevice.h> | ||
83 | #include <linux/skbuff.h> | ||
84 | #include <linux/if_arp.h> | ||
85 | #include <linux/ioport.h> | ||
86 | |||
87 | #include "et1310_phy.h" | ||
88 | #include "et1310_pm.h" | ||
89 | #include "et1310_jagcore.h" | ||
90 | |||
91 | #include "et131x_adapter.h" | ||
92 | #include "et131x_initpci.h" | ||
93 | #include "et131x_config.h" | ||
94 | |||
95 | #include "et1310_tx.h" | ||
96 | |||
97 | /* Data for debugging facilities */ | ||
98 | #ifdef CONFIG_ET131X_DEBUG | ||
99 | extern dbg_info_t *et131x_dbginfo; | ||
100 | #endif /* CONFIG_ET131X_DEBUG */ | ||
101 | |||
102 | /* Defines for Parameter Default/Min/Max vaules */ | ||
103 | #define PARM_SPEED_DUPLEX_DEF 0 | ||
104 | #define PARM_SPEED_DUPLEX_MIN 0 | ||
105 | #define PARM_SPEED_DUPLEX_MAX 5 | ||
106 | |||
107 | #define PARM_VLAN_TAG_DEF 0 | ||
108 | #define PARM_VLAN_TAG_MIN 0 | ||
109 | #define PARM_VLAN_TAG_MAX 4095 | ||
110 | |||
111 | #define PARM_FLOW_CTL_DEF 0 | ||
112 | #define PARM_FLOW_CTL_MIN 0 | ||
113 | #define PARM_FLOW_CTL_MAX 3 | ||
114 | |||
115 | #define PARM_WOL_LINK_DEF 3 | ||
116 | #define PARM_WOL_LINK_MIN 0 | ||
117 | #define PARM_WOL_LINK_MAX 3 | ||
118 | |||
119 | #define PARM_WOL_MATCH_DEF 7 | ||
120 | #define PARM_WOL_MATCH_MIN 0 | ||
121 | #define PARM_WOL_MATCH_MAX 7 | ||
122 | |||
123 | #define PARM_JUMBO_PKT_DEF 1514 | ||
124 | #define PARM_JUMBO_PKT_MIN 1514 | ||
125 | #define PARM_JUMBO_PKT_MAX 9216 | ||
126 | |||
127 | #define PARM_PHY_COMA_DEF 0 | ||
128 | #define PARM_PHY_COMA_MIN 0 | ||
129 | #define PARM_PHY_COMA_MAX 1 | ||
130 | |||
131 | #define PARM_RX_NUM_BUFS_DEF 4 | ||
132 | #define PARM_RX_NUM_BUFS_MIN 1 | ||
133 | #define PARM_RX_NUM_BUFS_MAX 64 | ||
134 | |||
135 | #define PARM_RX_TIME_INT_DEF 10 | ||
136 | #define PARM_RX_TIME_INT_MIN 2 | ||
137 | #define PARM_RX_TIME_INT_MAX 320 | ||
138 | |||
139 | #define PARM_TX_NUM_BUFS_DEF 4 | ||
140 | #define PARM_TX_NUM_BUFS_MIN 1 | ||
141 | #define PARM_TX_NUM_BUFS_MAX 40 | ||
142 | |||
143 | #define PARM_TX_TIME_INT_DEF 40 | ||
144 | #define PARM_TX_TIME_INT_MIN 1 | ||
145 | #define PARM_TX_TIME_INT_MAX 140 | ||
146 | |||
147 | #define PARM_RX_MEM_END_DEF 0x2bc | ||
148 | #define PARM_RX_MEM_END_MIN 0 | ||
149 | #define PARM_RX_MEM_END_MAX 0x3ff | ||
150 | |||
151 | #define PARM_MAC_STAT_DEF 1 | ||
152 | #define PARM_MAC_STAT_MIN 0 | ||
153 | #define PARM_MAC_STAT_MAX 1 | ||
154 | |||
155 | #define PARM_SC_GAIN_DEF 7 | ||
156 | #define PARM_SC_GAIN_MIN 0 | ||
157 | #define PARM_SC_GAIN_MAX 7 | ||
158 | |||
159 | #define PARM_PM_WOL_DEF 0 | ||
160 | #define PARM_PM_WOL_MIN 0 | ||
161 | #define PARM_PM_WOL_MAX 1 | ||
162 | |||
163 | #define PARM_NMI_DISABLE_DEF 0 | ||
164 | #define PARM_NMI_DISABLE_MIN 0 | ||
165 | #define PARM_NMI_DISABLE_MAX 2 | ||
166 | |||
167 | #define PARM_DMA_CACHE_DEF 0 | ||
168 | #define PARM_DMA_CACHE_MIN 0 | ||
169 | #define PARM_DMA_CACHE_MAX 15 | ||
170 | |||
171 | #define PARM_PHY_LOOPBK_DEF 0 | ||
172 | #define PARM_PHY_LOOPBK_MIN 0 | ||
173 | #define PARM_PHY_LOOPBK_MAX 1 | ||
174 | |||
175 | #define PARM_MAC_ADDRESS_DEF { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 } | ||
176 | |||
177 | /* Module parameter for disabling NMI | ||
178 | * et131x_speed_set : | ||
179 | * Set Link speed and dublex manually (0-5) [0] | ||
180 | * 1 : 10Mb Half-Duplex | ||
181 | * 2 : 10Mb Full-Duplex | ||
182 | * 3 : 100Mb Half-Duplex | ||
183 | * 4 : 100Mb Full-Duplex | ||
184 | * 5 : 1000Mb Full-Duplex | ||
185 | * 0 : Auto Speed Auto Dublex // default | ||
186 | */ | ||
187 | static u32 et131x_nmi_disable = PARM_NMI_DISABLE_DEF; | ||
188 | module_param(et131x_nmi_disable, uint, 0); | ||
189 | MODULE_PARM_DESC(et131x_nmi_disable, "Disable NMI (0-2) [0]"); | ||
190 | |||
191 | /* Module parameter for manual speed setting | ||
192 | * et131x_nmi_disable : | ||
193 | * Disable NMI (0-2) [0] | ||
194 | * 0 : | ||
195 | * 1 : | ||
196 | * 2 : | ||
197 | */ | ||
198 | static u32 et131x_speed_set = PARM_SPEED_DUPLEX_DEF; | ||
199 | module_param(et131x_speed_set, uint, 0); | ||
200 | MODULE_PARM_DESC(et131x_speed_set, | ||
201 | "Set Link speed and dublex manually (0-5) [0] \n 1 : 10Mb Half-Duplex \n 2 : 10Mb Full-Duplex \n 3 : 100Mb Half-Duplex \n 4 : 100Mb Full-Duplex \n 5 : 1000Mb Full-Duplex \n 0 : Auto Speed Auto Dublex"); | ||
202 | |||
203 | /** | ||
204 | * et131x_config_parse | ||
205 | * @pAdapter: pointer to the private adapter struct | ||
206 | * | ||
207 | * Parses a configuration from some location (module parameters, for example) | ||
208 | * into the private adapter struct | ||
209 | */ | ||
210 | void et131x_config_parse(struct et131x_adapter *pAdapter) | ||
211 | { | ||
212 | uint8_t macAddrDef[] = PARM_MAC_ADDRESS_DEF; | ||
213 | |||
214 | DBG_ENTER(et131x_dbginfo); | ||
215 | |||
216 | /* | ||
217 | * The NDIS driver uses the registry to store persistent per-device | ||
218 | * configuration, and reads this configuration into the appropriate | ||
219 | * elements of the private adapter structure on initialization. | ||
220 | * Because Linux has no analog to the registry, use this function to | ||
221 | * initialize the private adapter structure with a default | ||
222 | * configuration. | ||
223 | * | ||
224 | * One other possibility is to use a series of module parameters which | ||
225 | * can be passed in by the caller when the module is initialized. | ||
226 | * However, this implementation does not allow for seperate | ||
227 | * configurations in the event multiple devices are present, and hence | ||
228 | * will not suffice. | ||
229 | * | ||
230 | * If another method is derived which addresses this problem, this is | ||
231 | * where it should be implemented. | ||
232 | */ | ||
233 | |||
234 | /* Set the private adapter struct with default values for the | ||
235 | * corresponding parameters | ||
236 | */ | ||
237 | if (et131x_speed_set != PARM_SPEED_DUPLEX_DEF) { | ||
238 | DBG_VERBOSE(et131x_dbginfo, "Speed set manually to : %d \n", | ||
239 | et131x_speed_set); | ||
240 | pAdapter->SpeedDuplex = et131x_speed_set; | ||
241 | } else { | ||
242 | pAdapter->SpeedDuplex = PARM_SPEED_DUPLEX_DEF; | ||
243 | } | ||
244 | |||
245 | // pAdapter->SpeedDuplex = PARM_SPEED_DUPLEX_DEF; | ||
246 | |||
247 | pAdapter->RegistryVlanTag = PARM_VLAN_TAG_DEF; | ||
248 | pAdapter->RegistryFlowControl = PARM_FLOW_CTL_DEF; | ||
249 | pAdapter->RegistryWOLLink = PARM_WOL_LINK_DEF; | ||
250 | pAdapter->RegistryWOLMatch = PARM_WOL_MATCH_DEF; | ||
251 | pAdapter->RegistryJumboPacket = PARM_JUMBO_PKT_DEF; | ||
252 | pAdapter->RegistryPhyComa = PARM_PHY_COMA_DEF; | ||
253 | pAdapter->RegistryRxNumBuffers = PARM_RX_NUM_BUFS_DEF; | ||
254 | pAdapter->RegistryRxTimeInterval = PARM_RX_TIME_INT_DEF; | ||
255 | pAdapter->RegistryTxNumBuffers = PARM_TX_NUM_BUFS_DEF; | ||
256 | pAdapter->RegistryTxTimeInterval = PARM_TX_TIME_INT_DEF; | ||
257 | pAdapter->RegistryRxMemEnd = PARM_RX_MEM_END_DEF; | ||
258 | pAdapter->RegistryMACStat = PARM_MAC_STAT_DEF; | ||
259 | pAdapter->RegistrySCGain = PARM_SC_GAIN_DEF; | ||
260 | pAdapter->RegistryPMWOL = PARM_PM_WOL_DEF; | ||
261 | |||
262 | if (et131x_nmi_disable != PARM_NMI_DISABLE_DEF) { | ||
263 | pAdapter->RegistryNMIDisable = et131x_nmi_disable; | ||
264 | } else { | ||
265 | pAdapter->RegistryNMIDisable = PARM_NMI_DISABLE_DEF; | ||
266 | } | ||
267 | |||
268 | pAdapter->RegistryDMACache = PARM_DMA_CACHE_DEF; | ||
269 | pAdapter->RegistryPhyLoopbk = PARM_PHY_LOOPBK_DEF; | ||
270 | |||
271 | /* Set the MAC address to a default */ | ||
272 | memcpy(pAdapter->CurrentAddress, macAddrDef, ETH_ALEN); | ||
273 | pAdapter->bOverrideAddress = false; | ||
274 | |||
275 | DBG_TRACE(et131x_dbginfo, | ||
276 | "Default MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
277 | pAdapter->CurrentAddress[0], pAdapter->CurrentAddress[1], | ||
278 | pAdapter->CurrentAddress[2], pAdapter->CurrentAddress[3], | ||
279 | pAdapter->CurrentAddress[4], pAdapter->CurrentAddress[5]); | ||
280 | |||
281 | /* Decode SpeedDuplex | ||
282 | * | ||
283 | * Set up as if we are auto negotiating always and then change if we | ||
284 | * go into force mode | ||
285 | */ | ||
286 | pAdapter->AiForceSpeed = 0; // Auto speed | ||
287 | pAdapter->AiForceDpx = 0; // Auto FDX | ||
288 | |||
289 | /* If we are the 10/100 device, and gigabit is somehow requested then | ||
290 | * knock it down to 100 full. | ||
291 | */ | ||
292 | if ((pAdapter->DeviceID == ET131X_PCI_DEVICE_ID_FAST) && | ||
293 | (pAdapter->SpeedDuplex == 5)) { | ||
294 | pAdapter->SpeedDuplex = 4; | ||
295 | } | ||
296 | |||
297 | switch (pAdapter->SpeedDuplex) { | ||
298 | case 1: // 10Mb Half-Duplex | ||
299 | pAdapter->AiForceSpeed = 10; | ||
300 | pAdapter->AiForceDpx = 1; | ||
301 | break; | ||
302 | |||
303 | case 2: // 10Mb Full-Duplex | ||
304 | pAdapter->AiForceSpeed = 10; | ||
305 | pAdapter->AiForceDpx = 2; | ||
306 | break; | ||
307 | |||
308 | case 3: // 100Mb Half-Duplex | ||
309 | pAdapter->AiForceSpeed = 100; | ||
310 | pAdapter->AiForceDpx = 1; | ||
311 | break; | ||
312 | |||
313 | case 4: // 100Mb Full-Duplex | ||
314 | pAdapter->AiForceSpeed = 100; | ||
315 | pAdapter->AiForceDpx = 2; | ||
316 | break; | ||
317 | |||
318 | case 5: // 1000Mb Full-Duplex | ||
319 | pAdapter->AiForceSpeed = 1000; | ||
320 | pAdapter->AiForceDpx = 2; | ||
321 | break; | ||
322 | } | ||
323 | |||
324 | DBG_LEAVE(et131x_dbginfo); | ||
325 | } | ||
diff --git a/drivers/staging/et131x/et131x_config.h b/drivers/staging/et131x/et131x_config.h new file mode 100644 index 000000000000..642c0f6dd6f3 --- /dev/null +++ b/drivers/staging/et131x/et131x_config.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_config.h - Defines, structs, enums, prototypes, etc. to support | ||
12 | * et131x_config.c | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef __ET131X_CONFIG_H__ | ||
60 | #define __ET131X_CONFIG_H__ | ||
61 | |||
62 | /* Forward declaration of the private adapter structure */ | ||
63 | struct et131x_adapter; | ||
64 | |||
65 | void et131x_config_parse(struct et131x_adapter *adapter); | ||
66 | |||
67 | #endif /* __ET131X_CONFIG_H__ */ | ||
diff --git a/drivers/staging/et131x/et131x_debug.c b/drivers/staging/et131x/et131x_debug.c new file mode 100644 index 000000000000..9ee5bce92c27 --- /dev/null +++ b/drivers/staging/et131x/et131x_debug.c | |||
@@ -0,0 +1,218 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_debug.c - Routines used for debugging. | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #ifdef CONFIG_ET131X_DEBUG | ||
59 | |||
60 | #include "et131x_version.h" | ||
61 | #include "et131x_debug.h" | ||
62 | #include "et131x_defs.h" | ||
63 | |||
64 | #include <linux/pci.h> | ||
65 | #include <linux/init.h> | ||
66 | #include <linux/module.h> | ||
67 | #include <linux/types.h> | ||
68 | #include <linux/kernel.h> | ||
69 | |||
70 | #include <linux/sched.h> | ||
71 | #include <linux/ptrace.h> | ||
72 | #include <linux/slab.h> | ||
73 | #include <linux/ctype.h> | ||
74 | #include <linux/string.h> | ||
75 | #include <linux/timer.h> | ||
76 | #include <linux/interrupt.h> | ||
77 | #include <linux/in.h> | ||
78 | #include <linux/delay.h> | ||
79 | #include <asm/io.h> | ||
80 | #include <asm/system.h> | ||
81 | #include <asm/bitops.h> | ||
82 | |||
83 | #include <linux/netdevice.h> | ||
84 | #include <linux/etherdevice.h> | ||
85 | #include <linux/skbuff.h> | ||
86 | #include <linux/if_arp.h> | ||
87 | #include <linux/ioport.h> | ||
88 | #include <linux/random.h> | ||
89 | |||
90 | #include "et1310_phy.h" | ||
91 | #include "et1310_pm.h" | ||
92 | #include "et1310_jagcore.h" | ||
93 | |||
94 | #include "et131x_adapter.h" | ||
95 | #include "et131x_netdev.h" | ||
96 | #include "et131x_config.h" | ||
97 | #include "et131x_isr.h" | ||
98 | |||
99 | #include "et1310_address_map.h" | ||
100 | #include "et1310_jagcore.h" | ||
101 | #include "et1310_tx.h" | ||
102 | #include "et1310_rx.h" | ||
103 | #include "et1310_mac.h" | ||
104 | |||
105 | /* Data for debugging facilities */ | ||
106 | extern dbg_info_t *et131x_dbginfo; | ||
107 | |||
108 | /** | ||
109 | * DumpTxQueueContents - Dump out the tx queue and the shadow pointers | ||
110 | * @pAdapter: pointer to our adapter structure | ||
111 | */ | ||
112 | void DumpTxQueueContents(int dbgLvl, struct et131x_adapter *pAdapter) | ||
113 | { | ||
114 | MMC_t __iomem *mmc = &pAdapter->CSRAddress->mmc; | ||
115 | uint32_t TxQueueAddr; | ||
116 | |||
117 | if (DBG_FLAGS(et131x_dbginfo) & dbgLvl) { | ||
118 | for (TxQueueAddr = 0x200; TxQueueAddr < 0x3ff; TxQueueAddr++) { | ||
119 | MMC_SRAM_ACCESS_t sram_access; | ||
120 | |||
121 | sram_access.value = readl(&mmc->sram_access.value); | ||
122 | sram_access.bits.req_addr = TxQueueAddr; | ||
123 | sram_access.bits.req_access = 1; | ||
124 | writel(sram_access.value, &mmc->sram_access.value); | ||
125 | |||
126 | DBG_PRINT("Addr 0x%x, Access 0x%08x\t" | ||
127 | "Value 1 0x%08x, Value 2 0x%08x, " | ||
128 | "Value 3 0x%08x, Value 4 0x%08x, \n", | ||
129 | TxQueueAddr, | ||
130 | readl(&mmc->sram_access.value), | ||
131 | readl(&mmc->sram_word1), | ||
132 | readl(&mmc->sram_word2), | ||
133 | readl(&mmc->sram_word3), | ||
134 | readl(&mmc->sram_word4)); | ||
135 | } | ||
136 | |||
137 | DBG_PRINT("Shadow Pointers 0x%08x\n", | ||
138 | readl(&pAdapter->CSRAddress->txmac.shadow_ptr.value)); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | /** | ||
143 | * DumpDeviceBlock | ||
144 | * @pAdapter: pointer to our adapter | ||
145 | * | ||
146 | * Dumps the first 64 regs of each block of the et-1310 (each block is | ||
147 | * mapped to a new page, each page is 4096 bytes). | ||
148 | */ | ||
149 | #define NUM_BLOCKS 8 | ||
150 | void DumpDeviceBlock(int dbgLvl, struct et131x_adapter *pAdapter, | ||
151 | uint32_t Block) | ||
152 | { | ||
153 | uint32_t Address1, Address2; | ||
154 | uint32_t __iomem *BigDevicePointer = | ||
155 | (uint32_t __iomem *) pAdapter->CSRAddress; | ||
156 | const char *BlockNames[NUM_BLOCKS] = { | ||
157 | "Global", "Tx DMA", "Rx DMA", "Tx MAC", | ||
158 | "Rx MAC", "MAC", "MAC Stat", "MMC" | ||
159 | }; | ||
160 | |||
161 | /* Output the debug counters to the debug terminal */ | ||
162 | if (DBG_FLAGS(et131x_dbginfo) & dbgLvl) { | ||
163 | DBG_PRINT("%s block\n", BlockNames[Block]); | ||
164 | BigDevicePointer += Block * 1024; | ||
165 | for (Address1 = 0; Address1 < 8; Address1++) { | ||
166 | for (Address2 = 0; Address2 < 8; Address2++) { | ||
167 | if (Block == 0 && | ||
168 | (Address1 * 8 + Address2) == 6) { | ||
169 | DBG_PRINT(" ISR , "); | ||
170 | } else { | ||
171 | DBG_PRINT("0x%08x, ", | ||
172 | readl(BigDevicePointer++)); | ||
173 | } | ||
174 | } | ||
175 | DBG_PRINT("\n"); | ||
176 | } | ||
177 | DBG_PRINT("\n"); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * DumpDeviceReg | ||
183 | * @pAdapter: pointer to our adapter | ||
184 | * | ||
185 | * Dumps the first 64 regs of each block of the et-1310 (each block is | ||
186 | * mapped to a new page, each page is 4096 bytes). | ||
187 | */ | ||
188 | void DumpDeviceReg(int dbgLvl, struct et131x_adapter *pAdapter) | ||
189 | { | ||
190 | uint32_t Address1, Address2; | ||
191 | uint32_t Block; | ||
192 | uint32_t __iomem *BigDevicePointer = | ||
193 | (uint32_t __iomem *) pAdapter->CSRAddress; | ||
194 | uint32_t __iomem *Pointer; | ||
195 | const char *BlockNames[NUM_BLOCKS] = { | ||
196 | "Global", "Tx DMA", "Rx DMA", "Tx MAC", | ||
197 | "Rx MAC", "MAC", "MAC Stat", "MMC" | ||
198 | }; | ||
199 | |||
200 | /* Output the debug counters to the debug terminal */ | ||
201 | if (DBG_FLAGS(et131x_dbginfo) & dbgLvl) { | ||
202 | for (Block = 0; Block < NUM_BLOCKS; Block++) { | ||
203 | DBG_PRINT("%s block\n", BlockNames[Block]); | ||
204 | Pointer = BigDevicePointer + (Block * 1024); | ||
205 | |||
206 | for (Address1 = 0; Address1 < 8; Address1++) { | ||
207 | for (Address2 = 0; Address2 < 8; Address2++) { | ||
208 | DBG_PRINT("0x%08x, ", | ||
209 | readl(Pointer++)); | ||
210 | } | ||
211 | DBG_PRINT("\n"); | ||
212 | } | ||
213 | DBG_PRINT("\n"); | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | |||
218 | #endif // CONFIG_ET131X_DEBUG | ||
diff --git a/drivers/staging/et131x/et131x_debug.h b/drivers/staging/et131x/et131x_debug.h new file mode 100644 index 000000000000..dab608031d0b --- /dev/null +++ b/drivers/staging/et131x/et131x_debug.h | |||
@@ -0,0 +1,201 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_debug.h - Defines, structs, enums, prototypes, etc. used for | ||
12 | * outputting debug messages to the system logging facility | ||
13 | * (ksyslogd) | ||
14 | * | ||
15 | *------------------------------------------------------------------------------ | ||
16 | * | ||
17 | * SOFTWARE LICENSE | ||
18 | * | ||
19 | * This software is provided subject to the following terms and conditions, | ||
20 | * which you should read carefully before using the software. Using this | ||
21 | * software indicates your acceptance of these terms and conditions. If you do | ||
22 | * not agree with these terms and conditions, do not use the software. | ||
23 | * | ||
24 | * Copyright © 2005 Agere Systems Inc. | ||
25 | * All rights reserved. | ||
26 | * | ||
27 | * Redistribution and use in source or binary forms, with or without | ||
28 | * modifications, are permitted provided that the following conditions are met: | ||
29 | * | ||
30 | * . Redistributions of source code must retain the above copyright notice, this | ||
31 | * list of conditions and the following Disclaimer as comments in the code as | ||
32 | * well as in the documentation and/or other materials provided with the | ||
33 | * distribution. | ||
34 | * | ||
35 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
36 | * this list of conditions and the following Disclaimer in the documentation | ||
37 | * and/or other materials provided with the distribution. | ||
38 | * | ||
39 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
40 | * may be used to endorse or promote products derived from this software | ||
41 | * without specific prior written permission. | ||
42 | * | ||
43 | * Disclaimer | ||
44 | * | ||
45 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
46 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
47 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
48 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
49 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
50 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
51 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
52 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
53 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
54 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
55 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
56 | * DAMAGE. | ||
57 | * | ||
58 | */ | ||
59 | |||
60 | #ifndef __ET131X_DBG_H__ | ||
61 | #define __ET131X_DBG_H__ | ||
62 | |||
63 | /* Define Masks for debugging types/levels */ | ||
64 | #define DBG_ERROR_ON 0x00000001L | ||
65 | #define DBG_WARNING_ON 0x00000002L | ||
66 | #define DBG_NOTICE_ON 0x00000004L | ||
67 | #define DBG_TRACE_ON 0x00000008L | ||
68 | #define DBG_VERBOSE_ON 0x00000010L | ||
69 | #define DBG_PARAM_ON 0x00000020L | ||
70 | #define DBG_BREAK_ON 0x00000040L | ||
71 | #define DBG_RX_ON 0x00000100L | ||
72 | #define DBG_TX_ON 0x00000200L | ||
73 | |||
74 | #ifdef CONFIG_ET131X_DEBUG | ||
75 | |||
76 | /* | ||
77 | * Set the level of debugging if not done with a preprocessor define. See | ||
78 | * et131x_main.c, function et131x_init_module() for how the debug level | ||
79 | * translates into the types of messages displayed. | ||
80 | */ | ||
81 | #ifndef DBG_LVL | ||
82 | #define DBG_LVL 3 | ||
83 | #endif /* DBG_LVL */ | ||
84 | |||
85 | #define DBG_DEFAULTS (DBG_ERROR_ON | DBG_WARNING_ON | DBG_BREAK_ON ) | ||
86 | |||
87 | #define DBG_FLAGS(A) (A)->dbgFlags | ||
88 | #define DBG_NAME(A) (A)->dbgName | ||
89 | #define DBG_LEVEL(A) (A)->dbgLevel | ||
90 | |||
91 | #ifndef DBG_PRINT | ||
92 | #define DBG_PRINT(S...) printk(KERN_DEBUG S) | ||
93 | #endif /* DBG_PRINT */ | ||
94 | |||
95 | #ifndef DBG_PRINTC | ||
96 | #define DBG_PRINTC(S...) printk(S) | ||
97 | #endif /* DBG_PRINTC */ | ||
98 | |||
99 | #ifndef DBG_TRAP | ||
100 | #define DBG_TRAP {} /* BUG() */ | ||
101 | #endif /* DBG_TRAP */ | ||
102 | |||
103 | #define _ENTER_STR ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" | ||
104 | #define _LEAVE_STR "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" | ||
105 | |||
106 | #define _DBG_ENTER(A) printk(KERN_DEBUG "%s:%.*s:%s\n", DBG_NAME(A), \ | ||
107 | ++DBG_LEVEL(A), _ENTER_STR, __func__) | ||
108 | #define _DBG_LEAVE(A) printk(KERN_DEBUG "%s:%.*s:%s\n", DBG_NAME(A), \ | ||
109 | DBG_LEVEL(A)--, _LEAVE_STR, __func__) | ||
110 | |||
111 | #define DBG_ENTER(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ | ||
112 | _DBG_ENTER(A);} | ||
113 | |||
114 | #define DBG_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ | ||
115 | _DBG_LEAVE(A);} | ||
116 | |||
117 | #define DBG_PARAM(A,N,F,S...) {if (DBG_FLAGS(A) & DBG_PARAM_ON) \ | ||
118 | DBG_PRINT(" %s -- "F"\n",N,S);} | ||
119 | |||
120 | #define DBG_ERROR(A,S...) \ | ||
121 | if (DBG_FLAGS(A) & DBG_ERROR_ON) { \ | ||
122 | DBG_PRINT("%s:ERROR:%s ",DBG_NAME(A), __func__); \ | ||
123 | DBG_PRINTC(S); \ | ||
124 | DBG_TRAP; \ | ||
125 | } | ||
126 | |||
127 | #define DBG_WARNING(A,S...) {if (DBG_FLAGS(A) & DBG_WARNING_ON) \ | ||
128 | {DBG_PRINT("%s:WARNING:%s ",DBG_NAME(A),__func__);DBG_PRINTC(S);}} | ||
129 | |||
130 | #define DBG_NOTICE(A,S...) {if (DBG_FLAGS(A) & DBG_NOTICE_ON) \ | ||
131 | {DBG_PRINT("%s:NOTICE:%s ",DBG_NAME(A),__func__);DBG_PRINTC(S);}} | ||
132 | |||
133 | #define DBG_TRACE(A,S...) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ | ||
134 | {DBG_PRINT("%s:TRACE:%s ",DBG_NAME(A), __func__);DBG_PRINTC(S);}} | ||
135 | |||
136 | #define DBG_VERBOSE(A,S...) {if (DBG_FLAGS(A) & DBG_VERBOSE_ON) \ | ||
137 | {DBG_PRINT("%s:VERBOSE:%s ",DBG_NAME(A), __func__);DBG_PRINTC(S);}} | ||
138 | |||
139 | #define DBG_RX(A,S...) {if (DBG_FLAGS(A) & DBG_RX_ON) \ | ||
140 | {DBG_PRINT(S);}} | ||
141 | |||
142 | #define DBG_RX_ENTER(A) {if (DBG_FLAGS(A) & DBG_RX_ON) \ | ||
143 | _DBG_ENTER(A);} | ||
144 | |||
145 | #define DBG_RX_LEAVE(A) {if (DBG_FLAGS(A) & DBG_RX_ON) \ | ||
146 | _DBG_LEAVE(A);} | ||
147 | |||
148 | #define DBG_TX(A,S...) {if (DBG_FLAGS(A) & DBG_TX_ON) \ | ||
149 | {DBG_PRINT(S);}} | ||
150 | |||
151 | #define DBG_TX_ENTER(A) {if (DBG_FLAGS(A) & DBG_TX_ON) \ | ||
152 | _DBG_ENTER(A);} | ||
153 | |||
154 | #define DBG_TX_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TX_ON) \ | ||
155 | _DBG_LEAVE(A);} | ||
156 | |||
157 | #define DBG_ASSERT(C) {if (!(C)) \ | ||
158 | {DBG_PRINT("ASSERT(%s) -- %s#%d (%s)\n", \ | ||
159 | #C,__FILE__,__LINE__,__func__); \ | ||
160 | DBG_TRAP;}} | ||
161 | #define STATIC | ||
162 | |||
163 | typedef struct { | ||
164 | char *dbgName; | ||
165 | int dbgLevel; | ||
166 | unsigned long dbgFlags; | ||
167 | } dbg_info_t; | ||
168 | |||
169 | #else /* CONFIG_ET131X_DEBUG */ | ||
170 | |||
171 | #define DBG_DEFN | ||
172 | #define DBG_TRAP | ||
173 | #define DBG_PRINT(S...) | ||
174 | #define DBG_ENTER(A) | ||
175 | #define DBG_LEAVE(A) | ||
176 | #define DBG_PARAM(A,N,F,S...) | ||
177 | #define DBG_ERROR(A,S...) | ||
178 | #define DBG_WARNING(A,S...) | ||
179 | #define DBG_NOTICE(A,S...) | ||
180 | #define DBG_TRACE(A,S...) | ||
181 | #define DBG_VERBOSE(A,S...) | ||
182 | #define DBG_RX(A,S...) | ||
183 | #define DBG_RX_ENTER(A) | ||
184 | #define DBG_RX_LEAVE(A) | ||
185 | #define DBG_TX(A,S...) | ||
186 | #define DBG_TX_ENTER(A) | ||
187 | #define DBG_TX_LEAVE(A) | ||
188 | #define DBG_ASSERT(C) | ||
189 | #define STATIC static | ||
190 | |||
191 | #endif /* CONFIG_ET131X_DEBUG */ | ||
192 | |||
193 | /* Forward declaration of the private adapter structure */ | ||
194 | struct et131x_adapter; | ||
195 | |||
196 | void DumpTxQueueContents(int dbgLvl, struct et131x_adapter *adapter); | ||
197 | void DumpDeviceBlock(int dbgLvl, struct et131x_adapter *adapter, | ||
198 | unsigned int Block); | ||
199 | void DumpDeviceReg(int dbgLvl, struct et131x_adapter *adapter); | ||
200 | |||
201 | #endif /* __ET131X_DBG_H__ */ | ||
diff --git a/drivers/staging/et131x/et131x_defs.h b/drivers/staging/et131x/et131x_defs.h new file mode 100644 index 000000000000..886cb78698ef --- /dev/null +++ b/drivers/staging/et131x/et131x_defs.h | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_defs.h - Defines, structs, enums, prototypes, etc. to assist with OS | ||
12 | * compatibility | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef __ET131X_DEFS_H__ | ||
60 | #define __ET131X_DEFS_H__ | ||
61 | |||
62 | /* Packet and header sizes */ | ||
63 | #define NIC_MIN_PACKET_SIZE 60 | ||
64 | #define NIC_HEADER_SIZE ETH_HLEN /* 14 */ | ||
65 | |||
66 | /* Multicast list size */ | ||
67 | #define NIC_MAX_MCAST_LIST 128 | ||
68 | |||
69 | /* Supported Filters */ | ||
70 | #define ET131X_PACKET_TYPE_DIRECTED 0x0001 | ||
71 | #define ET131X_PACKET_TYPE_MULTICAST 0x0002 | ||
72 | #define ET131X_PACKET_TYPE_BROADCAST 0x0004 | ||
73 | #define ET131X_PACKET_TYPE_PROMISCUOUS 0x0008 | ||
74 | #define ET131X_PACKET_TYPE_ALL_MULTICAST 0x0010 | ||
75 | |||
76 | /* Tx Timeout */ | ||
77 | #define ET131X_TX_TIMEOUT (1 * HZ) | ||
78 | #define NIC_SEND_HANG_THRESHOLD 0 | ||
79 | |||
80 | /* MP_TCB flags */ | ||
81 | #define fMP_DEST_MULTI 0x00000001 | ||
82 | #define fMP_DEST_BROAD 0x00000002 | ||
83 | |||
84 | /* MP_ADAPTER flags */ | ||
85 | #define fMP_ADAPTER_RECV_LOOKASIDE 0x00000004 | ||
86 | #define fMP_ADAPTER_INTERRUPT_IN_USE 0x00000008 | ||
87 | #define fMP_ADAPTER_SECONDARY 0x00000010 | ||
88 | |||
89 | /* MP_SHARED flags */ | ||
90 | #define fMP_ADAPTER_SHUTDOWN 0x00100000 | ||
91 | #define fMP_ADAPTER_LOWER_POWER 0x00200000 | ||
92 | |||
93 | #define fMP_ADAPTER_NON_RECOVER_ERROR 0x00800000 | ||
94 | #define fMP_ADAPTER_RESET_IN_PROGRESS 0x01000000 | ||
95 | #define fMP_ADAPTER_NO_CABLE 0x02000000 | ||
96 | #define fMP_ADAPTER_HARDWARE_ERROR 0x04000000 | ||
97 | #define fMP_ADAPTER_REMOVE_IN_PROGRESS 0x08000000 | ||
98 | #define fMP_ADAPTER_HALT_IN_PROGRESS 0x10000000 | ||
99 | #define fMP_ADAPTER_LINK_DETECTION 0x20000000 | ||
100 | |||
101 | #define fMP_ADAPTER_FAIL_SEND_MASK 0x3ff00000 | ||
102 | #define fMP_ADAPTER_NOT_READY_MASK 0x3ff00000 | ||
103 | |||
104 | /* Some offsets in PCI config space that are actually used. */ | ||
105 | #define ET1310_PCI_PM_CAPABILITY 0x40 | ||
106 | #define ET1310_PCI_PM_CSR 0x44 | ||
107 | #define ET1310_PCI_MAX_PYLD 0x4C | ||
108 | #define ET1310_PCI_DEV_CTRL 0x50 | ||
109 | #define ET1310_PCI_DEV_STAT 0x52 | ||
110 | #define ET1310_NMI_DISABLE 0x61 | ||
111 | #define ET1310_PCI_MAC_ADDRESS 0xA4 | ||
112 | #define ET1310_PCI_EEPROM_STATUS 0xB2 | ||
113 | #define ET1310_PCI_PHY_INDEX_REG 0xB4 | ||
114 | #define ET1310_PCI_ACK_NACK 0xC0 | ||
115 | #define ET1310_PCI_REPLAY 0xC2 | ||
116 | #define ET1310_PCI_L0L1LATENCY 0xCF | ||
117 | #define ET1310_PCI_SEL_PHY_CTRL 0xE4 | ||
118 | #define ET1310_PCI_ADVANCED_ERR 0x100 | ||
119 | |||
120 | /* PCI Vendor/Product IDs */ | ||
121 | #define ET131X_PCI_VENDOR_ID 0x11C1 // Agere Systems | ||
122 | #define ET131X_PCI_DEVICE_ID_GIG 0xED00 // ET1310 1000 Base-T | ||
123 | #define ET131X_PCI_DEVICE_ID_FAST 0xED01 // ET1310 100 Base-T | ||
124 | |||
125 | /* Define order of magnitude converter */ | ||
126 | #define NANO_IN_A_MICRO 1000 | ||
127 | |||
128 | #endif /* __ET131X_DEFS_H__ */ | ||
diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c new file mode 100644 index 000000000000..4c6f171f5b7c --- /dev/null +++ b/drivers/staging/et131x/et131x_initpci.c | |||
@@ -0,0 +1,1046 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_initpci.c - Routines and data used to register the driver with the | ||
12 | * PCI (and PCI Express) subsystem, as well as basic driver | ||
13 | * init and startup. | ||
14 | * | ||
15 | *------------------------------------------------------------------------------ | ||
16 | * | ||
17 | * SOFTWARE LICENSE | ||
18 | * | ||
19 | * This software is provided subject to the following terms and conditions, | ||
20 | * which you should read carefully before using the software. Using this | ||
21 | * software indicates your acceptance of these terms and conditions. If you do | ||
22 | * not agree with these terms and conditions, do not use the software. | ||
23 | * | ||
24 | * Copyright © 2005 Agere Systems Inc. | ||
25 | * All rights reserved. | ||
26 | * | ||
27 | * Redistribution and use in source or binary forms, with or without | ||
28 | * modifications, are permitted provided that the following conditions are met: | ||
29 | * | ||
30 | * . Redistributions of source code must retain the above copyright notice, this | ||
31 | * list of conditions and the following Disclaimer as comments in the code as | ||
32 | * well as in the documentation and/or other materials provided with the | ||
33 | * distribution. | ||
34 | * | ||
35 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
36 | * this list of conditions and the following Disclaimer in the documentation | ||
37 | * and/or other materials provided with the distribution. | ||
38 | * | ||
39 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
40 | * may be used to endorse or promote products derived from this software | ||
41 | * without specific prior written permission. | ||
42 | * | ||
43 | * Disclaimer | ||
44 | * | ||
45 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
46 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
47 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
48 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
49 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
50 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
51 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
52 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
53 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
54 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
55 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
56 | * DAMAGE. | ||
57 | * | ||
58 | */ | ||
59 | |||
60 | #include "et131x_version.h" | ||
61 | #include "et131x_debug.h" | ||
62 | #include "et131x_defs.h" | ||
63 | |||
64 | #include <linux/pci.h> | ||
65 | #include <linux/init.h> | ||
66 | #include <linux/module.h> | ||
67 | #include <linux/types.h> | ||
68 | #include <linux/kernel.h> | ||
69 | |||
70 | #include <linux/sched.h> | ||
71 | #include <linux/ptrace.h> | ||
72 | #include <linux/slab.h> | ||
73 | #include <linux/ctype.h> | ||
74 | #include <linux/string.h> | ||
75 | #include <linux/timer.h> | ||
76 | #include <linux/interrupt.h> | ||
77 | #include <linux/in.h> | ||
78 | #include <linux/delay.h> | ||
79 | #include <asm/io.h> | ||
80 | #include <asm/system.h> | ||
81 | #include <asm/bitops.h> | ||
82 | |||
83 | #include <linux/netdevice.h> | ||
84 | #include <linux/etherdevice.h> | ||
85 | #include <linux/skbuff.h> | ||
86 | #include <linux/if_arp.h> | ||
87 | #include <linux/ioport.h> | ||
88 | #include <linux/random.h> | ||
89 | |||
90 | #include "et1310_phy.h" | ||
91 | #include "et1310_pm.h" | ||
92 | #include "et1310_jagcore.h" | ||
93 | |||
94 | #include "et131x_adapter.h" | ||
95 | #include "et131x_netdev.h" | ||
96 | #include "et131x_config.h" | ||
97 | #include "et131x_isr.h" | ||
98 | |||
99 | #include "et1310_address_map.h" | ||
100 | #include "et1310_jagcore.h" | ||
101 | #include "et1310_tx.h" | ||
102 | #include "et1310_rx.h" | ||
103 | #include "et1310_mac.h" | ||
104 | #include "et1310_eeprom.h" | ||
105 | |||
106 | |||
107 | int __devinit et131x_pci_setup(struct pci_dev *pdev, | ||
108 | const struct pci_device_id *ent); | ||
109 | void __devexit et131x_pci_remove(struct pci_dev *pdev); | ||
110 | |||
111 | |||
112 | /* Modinfo parameters (filled out using defines from et131x_version.h) */ | ||
113 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
114 | MODULE_DESCRIPTION(DRIVER_INFO); | ||
115 | MODULE_LICENSE(DRIVER_LICENSE); | ||
116 | |||
117 | /* Module Parameters and related data for debugging facilities */ | ||
118 | #ifdef CONFIG_ET131X_DEBUG | ||
119 | static u32 et131x_debug_level = DBG_LVL; | ||
120 | static u32 et131x_debug_flags = DBG_DEFAULTS; | ||
121 | |||
122 | /* | ||
123 | et131x_debug_level : | ||
124 | Level of debugging desired (0-7) | ||
125 | 7 : DBG_RX_ON | DBG_TX_ON | ||
126 | 6 : DBG_PARAM_ON | ||
127 | 5 : DBG_VERBOSE_ON | ||
128 | 4 : DBG_TRACE_ON | ||
129 | 3 : DBG_NOTICE_ON | ||
130 | 2 : no debug info | ||
131 | 1 : no debug info | ||
132 | 0 : no debug info | ||
133 | */ | ||
134 | |||
135 | module_param(et131x_debug_level, uint, 0); | ||
136 | module_param(et131x_debug_flags, uint, 0); | ||
137 | |||
138 | MODULE_PARM_DESC(et131x_debug_level, "Level of debugging desired (0-7)"); | ||
139 | |||
140 | static dbg_info_t et131x_info = { DRIVER_NAME_EXT, 0, 0 }; | ||
141 | dbg_info_t *et131x_dbginfo = &et131x_info; | ||
142 | #endif /* CONFIG_ET131X_DEBUG */ | ||
143 | |||
144 | static struct pci_device_id et131x_pci_table[] __devinitdata = { | ||
145 | {ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_GIG, PCI_ANY_ID, | ||
146 | PCI_ANY_ID, 0, 0, 0UL}, | ||
147 | {ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_FAST, PCI_ANY_ID, | ||
148 | PCI_ANY_ID, 0, 0, 0UL}, | ||
149 | {0,} | ||
150 | }; | ||
151 | |||
152 | MODULE_DEVICE_TABLE(pci, et131x_pci_table); | ||
153 | |||
154 | static struct pci_driver et131x_driver = { | ||
155 | .name = DRIVER_NAME, | ||
156 | .id_table = et131x_pci_table, | ||
157 | .probe = et131x_pci_setup, | ||
158 | .remove = __devexit_p(et131x_pci_remove), | ||
159 | .suspend = NULL, //et131x_pci_suspend, | ||
160 | .resume = NULL, //et131x_pci_resume, | ||
161 | }; | ||
162 | |||
163 | |||
164 | /** | ||
165 | * et131x_init_module - The "main" entry point called on driver initialization | ||
166 | * | ||
167 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
168 | */ | ||
169 | int et131x_init_module(void) | ||
170 | { | ||
171 | int result; | ||
172 | |||
173 | #ifdef CONFIG_ET131X_DEBUG | ||
174 | /* Set the level of debug messages displayed using the module | ||
175 | * parameter | ||
176 | */ | ||
177 | et131x_dbginfo->dbgFlags = et131x_debug_flags; | ||
178 | |||
179 | switch (et131x_debug_level) { | ||
180 | case 7: | ||
181 | et131x_dbginfo->dbgFlags |= (DBG_RX_ON | DBG_TX_ON); | ||
182 | |||
183 | case 6: | ||
184 | et131x_dbginfo->dbgFlags |= DBG_PARAM_ON; | ||
185 | |||
186 | case 5: | ||
187 | et131x_dbginfo->dbgFlags |= DBG_VERBOSE_ON; | ||
188 | |||
189 | case 4: | ||
190 | et131x_dbginfo->dbgFlags |= DBG_TRACE_ON; | ||
191 | |||
192 | case 3: | ||
193 | et131x_dbginfo->dbgFlags |= DBG_NOTICE_ON; | ||
194 | |||
195 | case 2: | ||
196 | case 1: | ||
197 | case 0: | ||
198 | default: | ||
199 | break; | ||
200 | } | ||
201 | #endif /* CONFIG_ET131X_DEBUG */ | ||
202 | |||
203 | DBG_ENTER(et131x_dbginfo); | ||
204 | DBG_PRINT("%s\n", DRIVER_INFO); | ||
205 | |||
206 | result = pci_register_driver(&et131x_driver); | ||
207 | |||
208 | DBG_LEAVE(et131x_dbginfo); | ||
209 | return result; | ||
210 | } | ||
211 | |||
212 | /** | ||
213 | * et131x_cleanup_module - The entry point called on driver cleanup | ||
214 | */ | ||
215 | void et131x_cleanup_module(void) | ||
216 | { | ||
217 | DBG_ENTER(et131x_dbginfo); | ||
218 | |||
219 | pci_unregister_driver(&et131x_driver); | ||
220 | |||
221 | DBG_LEAVE(et131x_dbginfo); | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * These macros map the driver-specific init_module() and cleanup_module() | ||
226 | * routines so they can be called by the kernel. | ||
227 | */ | ||
228 | module_init(et131x_init_module); | ||
229 | module_exit(et131x_cleanup_module); | ||
230 | |||
231 | |||
232 | /** | ||
233 | * et131x_find_adapter - Find the adapter and get all the assigned resources | ||
234 | * @adapter: pointer to our private adapter structure | ||
235 | * | ||
236 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
237 | */ | ||
238 | int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev) | ||
239 | { | ||
240 | int result; | ||
241 | uint8_t eepromStat; | ||
242 | uint8_t maxPayload = 0; | ||
243 | uint8_t read_size_reg; | ||
244 | |||
245 | DBG_ENTER(et131x_dbginfo); | ||
246 | |||
247 | /* Allow disabling of Non-Maskable Interrupts in I/O space, to | ||
248 | * support validation. | ||
249 | */ | ||
250 | if (adapter->RegistryNMIDisable) { | ||
251 | uint8_t RegisterVal; | ||
252 | |||
253 | RegisterVal = inb(ET1310_NMI_DISABLE); | ||
254 | RegisterVal &= 0xf3; | ||
255 | |||
256 | if (adapter->RegistryNMIDisable == 2) { | ||
257 | RegisterVal |= 0xc; | ||
258 | } | ||
259 | |||
260 | outb(ET1310_NMI_DISABLE, RegisterVal); | ||
261 | } | ||
262 | |||
263 | /* We first need to check the EEPROM Status code located at offset | ||
264 | * 0xB2 of config space | ||
265 | */ | ||
266 | result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, | ||
267 | &eepromStat); | ||
268 | |||
269 | /* THIS IS A WORKAROUND: | ||
270 | * I need to call this function twice to get my card in a | ||
271 | * LG M1 Express Dual running. I tried also a msleep before this | ||
272 | * function, because I thougth there could be some time condidions | ||
273 | * but it didn't work. Call the whole function twice also work. | ||
274 | */ | ||
275 | result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, | ||
276 | &eepromStat); | ||
277 | if (result != PCIBIOS_SUCCESSFUL) { | ||
278 | DBG_ERROR(et131x_dbginfo, "Could not read PCI config space for " | ||
279 | "EEPROM Status\n"); | ||
280 | DBG_LEAVE(et131x_dbginfo); | ||
281 | return -EIO; | ||
282 | } | ||
283 | |||
284 | /* Determine if the error(s) we care about are present. If they are | ||
285 | * present, we need to fail. | ||
286 | */ | ||
287 | if (eepromStat & 0x4C) { | ||
288 | result = pci_read_config_byte(pdev, PCI_REVISION_ID, | ||
289 | &adapter->RevisionID); | ||
290 | if (result != PCIBIOS_SUCCESSFUL) { | ||
291 | DBG_ERROR(et131x_dbginfo, | ||
292 | "Could not read PCI config space for " | ||
293 | "Revision ID\n"); | ||
294 | DBG_LEAVE(et131x_dbginfo); | ||
295 | return -EIO; | ||
296 | } else if (adapter->RevisionID == 0x01) { | ||
297 | int32_t nLoop; | ||
298 | uint8_t ucTemp[4] = { 0xFE, 0x13, 0x10, 0xFF }; | ||
299 | |||
300 | /* Re-write the first 4 bytes if we have an eeprom | ||
301 | * present and the revision id is 1, this fixes the | ||
302 | * corruption seen with 1310 B Silicon | ||
303 | */ | ||
304 | for (nLoop = 0; nLoop < 3; nLoop++) { | ||
305 | EepromWriteByte(adapter, nLoop, ucTemp[nLoop], | ||
306 | 0, SINGLE_BYTE); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | DBG_ERROR(et131x_dbginfo, | ||
311 | "Fatal EEPROM Status Error - 0x%04x\n", eepromStat); | ||
312 | |||
313 | /* This error could mean that there was an error reading the | ||
314 | * eeprom or that the eeprom doesn't exist. We will treat | ||
315 | * each case the same and not try to gather additional | ||
316 | * information that normally would come from the eeprom, like | ||
317 | * MAC Address | ||
318 | */ | ||
319 | adapter->bEepromPresent = false; | ||
320 | |||
321 | DBG_LEAVE(et131x_dbginfo); | ||
322 | return -EIO; | ||
323 | } else { | ||
324 | DBG_TRACE(et131x_dbginfo, "EEPROM Status Code - 0x%04x\n", | ||
325 | eepromStat); | ||
326 | adapter->bEepromPresent = true; | ||
327 | } | ||
328 | |||
329 | /* Read the EEPROM for information regarding LED behavior. Refer to | ||
330 | * ET1310_phy.c, et131x_xcvr_init(), for its use. | ||
331 | */ | ||
332 | EepromReadByte(adapter, 0x70, &adapter->eepromData[0], 0, SINGLE_BYTE); | ||
333 | EepromReadByte(adapter, 0x71, &adapter->eepromData[1], 0, SINGLE_BYTE); | ||
334 | |||
335 | if (adapter->eepromData[0] != 0xcd) { | ||
336 | adapter->eepromData[1] = 0x00; // Disable all optional features | ||
337 | } | ||
338 | |||
339 | /* Let's set up the PORT LOGIC Register. First we need to know what | ||
340 | * the max_payload_size is | ||
341 | */ | ||
342 | result = pci_read_config_byte(pdev, ET1310_PCI_MAX_PYLD, &maxPayload); | ||
343 | if (result != PCIBIOS_SUCCESSFUL) { | ||
344 | DBG_ERROR(et131x_dbginfo, "Could not read PCI config space for " | ||
345 | "Max Payload Size\n"); | ||
346 | DBG_LEAVE(et131x_dbginfo); | ||
347 | return -EIO; | ||
348 | } | ||
349 | |||
350 | /* Program the Ack/Nak latency and replay timers */ | ||
351 | maxPayload &= 0x07; // Only the lower 3 bits are valid | ||
352 | |||
353 | if (maxPayload < 2) { | ||
354 | const uint16_t AckNak[2] = { 0x76, 0xD0 }; | ||
355 | const uint16_t Replay[2] = { 0x1E0, 0x2ED }; | ||
356 | |||
357 | result = pci_write_config_word(pdev, ET1310_PCI_ACK_NACK, | ||
358 | AckNak[maxPayload]); | ||
359 | if (result != PCIBIOS_SUCCESSFUL) { | ||
360 | DBG_ERROR(et131x_dbginfo, | ||
361 | "Could not write PCI config space " | ||
362 | "for ACK/NAK\n"); | ||
363 | DBG_LEAVE(et131x_dbginfo); | ||
364 | return -EIO; | ||
365 | } | ||
366 | |||
367 | result = pci_write_config_word(pdev, ET1310_PCI_REPLAY, | ||
368 | Replay[maxPayload]); | ||
369 | if (result != PCIBIOS_SUCCESSFUL) { | ||
370 | DBG_ERROR(et131x_dbginfo, | ||
371 | "Could not write PCI config space " | ||
372 | "for Replay Timer\n"); | ||
373 | DBG_LEAVE(et131x_dbginfo); | ||
374 | return -EIO; | ||
375 | } | ||
376 | } | ||
377 | |||
378 | /* l0s and l1 latency timers. We are using default values. | ||
379 | * Representing 001 for L0s and 010 for L1 | ||
380 | */ | ||
381 | result = pci_write_config_byte(pdev, ET1310_PCI_L0L1LATENCY, 0x11); | ||
382 | if (result != PCIBIOS_SUCCESSFUL) { | ||
383 | DBG_ERROR(et131x_dbginfo, | ||
384 | "Could not write PCI config space for " | ||
385 | "Latency Timers\n"); | ||
386 | DBG_LEAVE(et131x_dbginfo); | ||
387 | return -EIO; | ||
388 | } | ||
389 | |||
390 | /* Change the max read size to 2k */ | ||
391 | result = pci_read_config_byte(pdev, 0x51, &read_size_reg); | ||
392 | if (result != PCIBIOS_SUCCESSFUL) { | ||
393 | DBG_ERROR(et131x_dbginfo, | ||
394 | "Could not read PCI config space for Max read size\n"); | ||
395 | DBG_LEAVE(et131x_dbginfo); | ||
396 | return -EIO; | ||
397 | } | ||
398 | |||
399 | read_size_reg &= 0x8f; | ||
400 | read_size_reg |= 0x40; | ||
401 | |||
402 | result = pci_write_config_byte(pdev, 0x51, read_size_reg); | ||
403 | if (result != PCIBIOS_SUCCESSFUL) { | ||
404 | DBG_ERROR(et131x_dbginfo, | ||
405 | "Could not write PCI config space for Max read size\n"); | ||
406 | DBG_LEAVE(et131x_dbginfo); | ||
407 | return -EIO; | ||
408 | } | ||
409 | |||
410 | /* PCI Express Configuration registers 0x48-0x5B (Device Control) */ | ||
411 | result = pci_read_config_word(pdev, ET1310_PCI_DEV_CTRL, | ||
412 | &adapter->PciXDevCtl); | ||
413 | if (result != PCIBIOS_SUCCESSFUL) { | ||
414 | DBG_ERROR(et131x_dbginfo, | ||
415 | "Could not read PCI config space for PCI Express Dev Ctl\n"); | ||
416 | DBG_LEAVE(et131x_dbginfo); | ||
417 | return -EIO; | ||
418 | } | ||
419 | |||
420 | /* Get MAC address from config space if an eeprom exists, otherwise | ||
421 | * the MAC address there will not be valid | ||
422 | */ | ||
423 | if (adapter->bEepromPresent) { | ||
424 | int i; | ||
425 | |||
426 | for (i = 0; i < ETH_ALEN; i++) { | ||
427 | result = pci_read_config_byte( | ||
428 | pdev, ET1310_PCI_MAC_ADDRESS + i, | ||
429 | adapter->PermanentAddress + i); | ||
430 | if (result != PCIBIOS_SUCCESSFUL) { | ||
431 | DBG_ERROR(et131x_dbginfo, | ||
432 | "Could not read PCI config space for MAC address\n"); | ||
433 | DBG_LEAVE(et131x_dbginfo); | ||
434 | return -EIO; | ||
435 | } | ||
436 | } | ||
437 | } | ||
438 | |||
439 | DBG_LEAVE(et131x_dbginfo); | ||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | /** | ||
444 | * et131x_error_timer_handler | ||
445 | * @data: timer-specific variable; here a pointer to our adapter structure | ||
446 | * | ||
447 | * The routine called when the error timer expires, to track the number of | ||
448 | * recurring errors. | ||
449 | */ | ||
450 | void et131x_error_timer_handler(unsigned long data) | ||
451 | { | ||
452 | struct et131x_adapter *pAdapter = (struct et131x_adapter *) data; | ||
453 | PM_CSR_t pm_csr; | ||
454 | |||
455 | pm_csr.value = readl(&pAdapter->CSRAddress->global.pm_csr.value); | ||
456 | |||
457 | if (pm_csr.bits.pm_phy_sw_coma == 0) { | ||
458 | if (pAdapter->RegistryMACStat) { | ||
459 | UpdateMacStatHostCounters(pAdapter); | ||
460 | } | ||
461 | } else { | ||
462 | DBG_VERBOSE(et131x_dbginfo, | ||
463 | "No interrupts, in PHY coma, pm_csr = 0x%x\n", | ||
464 | pm_csr.value); | ||
465 | } | ||
466 | |||
467 | if (!pAdapter->Bmsr.bits.link_status && | ||
468 | pAdapter->RegistryPhyComa && | ||
469 | pAdapter->PoMgmt.TransPhyComaModeOnBoot < 11) { | ||
470 | pAdapter->PoMgmt.TransPhyComaModeOnBoot++; | ||
471 | } | ||
472 | |||
473 | if (pAdapter->PoMgmt.TransPhyComaModeOnBoot == 10) { | ||
474 | if (!pAdapter->Bmsr.bits.link_status | ||
475 | && pAdapter->RegistryPhyComa) { | ||
476 | if (pm_csr.bits.pm_phy_sw_coma == 0) { | ||
477 | // NOTE - This was originally a 'sync with interrupt'. How | ||
478 | // to do that under Linux? | ||
479 | et131x_enable_interrupts(pAdapter); | ||
480 | EnablePhyComa(pAdapter); | ||
481 | } | ||
482 | } | ||
483 | } | ||
484 | |||
485 | /* This is a periodic timer, so reschedule */ | ||
486 | mod_timer(&pAdapter->ErrorTimer, jiffies + | ||
487 | TX_ERROR_PERIOD * HZ / 1000); | ||
488 | } | ||
489 | |||
490 | /** | ||
491 | * et131x_link_detection_handler | ||
492 | * | ||
493 | * Timer function for link up at driver load time | ||
494 | */ | ||
495 | void et131x_link_detection_handler(unsigned long data) | ||
496 | { | ||
497 | struct et131x_adapter *pAdapter = (struct et131x_adapter *) data; | ||
498 | unsigned long lockflags; | ||
499 | |||
500 | /* Let everyone know that we have run */ | ||
501 | pAdapter->bLinkTimerActive = false; | ||
502 | |||
503 | if (pAdapter->MediaState == 0) { | ||
504 | spin_lock_irqsave(&pAdapter->Lock, lockflags); | ||
505 | |||
506 | pAdapter->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; | ||
507 | MP_CLEAR_FLAG(pAdapter, fMP_ADAPTER_LINK_DETECTION); | ||
508 | |||
509 | spin_unlock_irqrestore(&pAdapter->Lock, lockflags); | ||
510 | |||
511 | netif_carrier_off(pAdapter->netdev); | ||
512 | |||
513 | pAdapter->bSetPending = false; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | /** | ||
518 | * et131x_adapter_setup - Set the adapter up as per cassini+ documentation | ||
519 | * @adapter: pointer to our private adapter structure | ||
520 | * | ||
521 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
522 | */ | ||
523 | int et131x_adapter_setup(struct et131x_adapter *pAdapter) | ||
524 | { | ||
525 | int status = 0; | ||
526 | |||
527 | DBG_ENTER(et131x_dbginfo); | ||
528 | |||
529 | /* Configure the JAGCore */ | ||
530 | ConfigGlobalRegs(pAdapter); | ||
531 | |||
532 | ConfigMACRegs1(pAdapter); | ||
533 | ConfigMMCRegs(pAdapter); | ||
534 | |||
535 | ConfigRxMacRegs(pAdapter); | ||
536 | ConfigTxMacRegs(pAdapter); | ||
537 | |||
538 | ConfigRxDmaRegs(pAdapter); | ||
539 | ConfigTxDmaRegs(pAdapter); | ||
540 | |||
541 | ConfigMacStatRegs(pAdapter); | ||
542 | |||
543 | /* Move the following code to Timer function?? */ | ||
544 | status = et131x_xcvr_find(pAdapter); | ||
545 | |||
546 | if (status != 0) { | ||
547 | DBG_WARNING(et131x_dbginfo, "Could not find the xcvr\n"); | ||
548 | } | ||
549 | |||
550 | /* Prepare the TRUEPHY library. */ | ||
551 | ET1310_PhyInit(pAdapter); | ||
552 | |||
553 | /* Reset the phy now so changes take place */ | ||
554 | ET1310_PhyReset(pAdapter); | ||
555 | |||
556 | /* Power down PHY */ | ||
557 | ET1310_PhyPowerDown(pAdapter, 1); | ||
558 | |||
559 | /* | ||
560 | * We need to turn off 1000 base half dulplex, the mac does not | ||
561 | * support it. For the 10/100 part, turn off all gig advertisement | ||
562 | */ | ||
563 | if (pAdapter->DeviceID != ET131X_PCI_DEVICE_ID_FAST) { | ||
564 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL); | ||
565 | } else { | ||
566 | ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE); | ||
567 | } | ||
568 | |||
569 | /* Power up PHY */ | ||
570 | ET1310_PhyPowerDown(pAdapter, 0); | ||
571 | |||
572 | et131x_setphy_normal(pAdapter); | ||
573 | |||
574 | DBG_LEAVE(et131x_dbginfo); | ||
575 | return status; | ||
576 | } | ||
577 | |||
578 | /** | ||
579 | * et131x_setup_hardware_properties - set up the MAC Address on the ET1310 | ||
580 | * @adapter: pointer to our private adapter structure | ||
581 | */ | ||
582 | void et131x_setup_hardware_properties(struct et131x_adapter *adapter) | ||
583 | { | ||
584 | DBG_ENTER(et131x_dbginfo); | ||
585 | |||
586 | /* If have our default mac from registry and no mac address from | ||
587 | * EEPROM then we need to generate the last octet and set it on the | ||
588 | * device | ||
589 | */ | ||
590 | if (!adapter->bOverrideAddress) { | ||
591 | if (adapter->PermanentAddress[0] == 0x00 && | ||
592 | adapter->PermanentAddress[1] == 0x00 && | ||
593 | adapter->PermanentAddress[2] == 0x00 && | ||
594 | adapter->PermanentAddress[3] == 0x00 && | ||
595 | adapter->PermanentAddress[4] == 0x00 && | ||
596 | adapter->PermanentAddress[5] == 0x00) { | ||
597 | /* | ||
598 | * We need to randomly generate the last octet so we | ||
599 | * decrease our chances of setting the mac address to | ||
600 | * same as another one of our cards in the system | ||
601 | */ | ||
602 | get_random_bytes(&adapter->CurrentAddress[5], 1); | ||
603 | |||
604 | /* | ||
605 | * We have the default value in the register we are | ||
606 | * working with so we need to copy the current | ||
607 | * address into the permanent address | ||
608 | */ | ||
609 | memcpy(adapter->PermanentAddress, | ||
610 | adapter->CurrentAddress, ETH_ALEN); | ||
611 | } else { | ||
612 | /* We do not have an override address, so set the | ||
613 | * current address to the permanent address and add | ||
614 | * it to the device | ||
615 | */ | ||
616 | memcpy(adapter->CurrentAddress, | ||
617 | adapter->PermanentAddress, ETH_ALEN); | ||
618 | } | ||
619 | } | ||
620 | |||
621 | DBG_LEAVE(et131x_dbginfo); | ||
622 | } | ||
623 | |||
624 | /** | ||
625 | * et131x_soft_reset - Issue a soft reset to the hardware, complete for ET1310 | ||
626 | * @adapter: pointer to our private adapter structure | ||
627 | */ | ||
628 | void et131x_soft_reset(struct et131x_adapter *adapter) | ||
629 | { | ||
630 | DBG_ENTER(et131x_dbginfo); | ||
631 | |||
632 | /* Disable MAC Core */ | ||
633 | writel(0xc00f0000, &adapter->CSRAddress->mac.cfg1.value); | ||
634 | |||
635 | /* Set everything to a reset value */ | ||
636 | writel(0x7F, &adapter->CSRAddress->global.sw_reset.value); | ||
637 | writel(0x000f0000, &adapter->CSRAddress->mac.cfg1.value); | ||
638 | writel(0x00000000, &adapter->CSRAddress->mac.cfg1.value); | ||
639 | |||
640 | DBG_LEAVE(et131x_dbginfo); | ||
641 | } | ||
642 | |||
643 | /** | ||
644 | * et131x_align_allocated_memory - Align allocated memory on a given boundary | ||
645 | * @adapter: pointer to our adapter structure | ||
646 | * @phys_addr: pointer to Physical address | ||
647 | * @offset: pointer to the offset variable | ||
648 | * @mask: correct mask | ||
649 | */ | ||
650 | void et131x_align_allocated_memory(struct et131x_adapter *adapter, | ||
651 | uint64_t *phys_addr, | ||
652 | uint64_t *offset, uint64_t mask) | ||
653 | { | ||
654 | uint64_t new_addr; | ||
655 | |||
656 | DBG_ENTER(et131x_dbginfo); | ||
657 | |||
658 | *offset = 0; | ||
659 | |||
660 | new_addr = *phys_addr & ~mask; | ||
661 | |||
662 | if (new_addr != *phys_addr) { | ||
663 | /* Move to next aligned block */ | ||
664 | new_addr += mask + 1; | ||
665 | /* Return offset for adjusting virt addr */ | ||
666 | *offset = new_addr - *phys_addr; | ||
667 | /* Return new physical address */ | ||
668 | *phys_addr = new_addr; | ||
669 | } | ||
670 | |||
671 | DBG_LEAVE(et131x_dbginfo); | ||
672 | } | ||
673 | |||
674 | /** | ||
675 | * et131x_adapter_memory_alloc | ||
676 | * @adapter: pointer to our private adapter structure | ||
677 | * | ||
678 | * Returns 0 on success, errno on failure (as defined in errno.h). | ||
679 | * | ||
680 | * Allocate all the memory blocks for send, receive and others. | ||
681 | */ | ||
682 | int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) | ||
683 | { | ||
684 | int status = 0; | ||
685 | |||
686 | DBG_ENTER(et131x_dbginfo); | ||
687 | |||
688 | do { | ||
689 | /* Allocate memory for the Tx Ring */ | ||
690 | status = et131x_tx_dma_memory_alloc(adapter); | ||
691 | if (status != 0) { | ||
692 | DBG_ERROR(et131x_dbginfo, | ||
693 | "et131x_tx_dma_memory_alloc FAILED\n"); | ||
694 | break; | ||
695 | } | ||
696 | |||
697 | /* Receive buffer memory allocation */ | ||
698 | status = et131x_rx_dma_memory_alloc(adapter); | ||
699 | if (status != 0) { | ||
700 | DBG_ERROR(et131x_dbginfo, | ||
701 | "et131x_rx_dma_memory_alloc FAILED\n"); | ||
702 | et131x_tx_dma_memory_free(adapter); | ||
703 | break; | ||
704 | } | ||
705 | |||
706 | /* Init receive data structures */ | ||
707 | status = et131x_init_recv(adapter); | ||
708 | if (status != 0) { | ||
709 | DBG_ERROR(et131x_dbginfo, "et131x_init_recv FAILED\n"); | ||
710 | et131x_tx_dma_memory_free(adapter); | ||
711 | et131x_rx_dma_memory_free(adapter); | ||
712 | break; | ||
713 | } | ||
714 | } while (0); | ||
715 | |||
716 | DBG_LEAVE(et131x_dbginfo); | ||
717 | return status; | ||
718 | } | ||
719 | |||
720 | /** | ||
721 | * et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx | ||
722 | * @adapter: pointer to our private adapter structure | ||
723 | */ | ||
724 | void et131x_adapter_memory_free(struct et131x_adapter *adapter) | ||
725 | { | ||
726 | DBG_ENTER(et131x_dbginfo); | ||
727 | |||
728 | /* Free DMA memory */ | ||
729 | et131x_tx_dma_memory_free(adapter); | ||
730 | et131x_rx_dma_memory_free(adapter); | ||
731 | |||
732 | DBG_LEAVE(et131x_dbginfo); | ||
733 | } | ||
734 | |||
735 | /** | ||
736 | * et131x_pci_remove | ||
737 | * @pdev: a pointer to the device's pci_dev structure | ||
738 | * | ||
739 | * Registered in the pci_driver structure, this function is called when the | ||
740 | * PCI subsystem detects that a PCI device which matches the information | ||
741 | * contained in the pci_device_id table has been removed. | ||
742 | */ | ||
743 | void __devexit et131x_pci_remove(struct pci_dev *pdev) | ||
744 | { | ||
745 | struct net_device *netdev; | ||
746 | struct et131x_adapter *adapter; | ||
747 | |||
748 | DBG_ENTER(et131x_dbginfo); | ||
749 | |||
750 | /* Retrieve the net_device pointer from the pci_dev struct, as well | ||
751 | * as the private adapter struct | ||
752 | */ | ||
753 | netdev = (struct net_device *) pci_get_drvdata(pdev); | ||
754 | adapter = netdev_priv(netdev); | ||
755 | |||
756 | /* Perform device cleanup */ | ||
757 | unregister_netdev(netdev); | ||
758 | et131x_adapter_memory_free(adapter); | ||
759 | iounmap(adapter->CSRAddress); | ||
760 | free_netdev(netdev); | ||
761 | pci_release_regions(pdev); | ||
762 | pci_disable_device(pdev); | ||
763 | |||
764 | DBG_LEAVE(et131x_dbginfo); | ||
765 | } | ||
766 | |||
767 | /** | ||
768 | * et131x_pci_setup - Perform device initialization | ||
769 | * @pdev: a pointer to the device's pci_dev structure | ||
770 | * @ent: this device's entry in the pci_device_id table | ||
771 | * | ||
772 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
773 | * | ||
774 | * Registered in the pci_driver structure, this function is called when the | ||
775 | * PCI subsystem finds a new PCI device which matches the information | ||
776 | * contained in the pci_device_id table. This routine is the equivalent to | ||
777 | * a device insertion routine. | ||
778 | */ | ||
779 | int __devinit et131x_pci_setup(struct pci_dev *pdev, | ||
780 | const struct pci_device_id *ent) | ||
781 | { | ||
782 | int result = 0; | ||
783 | int pm_cap; | ||
784 | bool pci_using_dac; | ||
785 | struct net_device *netdev = NULL; | ||
786 | struct et131x_adapter *adapter = NULL; | ||
787 | |||
788 | DBG_ENTER(et131x_dbginfo); | ||
789 | |||
790 | /* Enable the device via the PCI subsystem */ | ||
791 | result = pci_enable_device(pdev); | ||
792 | if (result != 0) { | ||
793 | DBG_ERROR(et131x_dbginfo, "pci_enable_device() failed\n"); | ||
794 | goto out; | ||
795 | } | ||
796 | |||
797 | /* Perform some basic PCI checks */ | ||
798 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | ||
799 | DBG_ERROR(et131x_dbginfo, | ||
800 | "Can't find PCI device's base address\n"); | ||
801 | result = -ENODEV; | ||
802 | goto out; | ||
803 | } | ||
804 | |||
805 | result = pci_request_regions(pdev, DRIVER_NAME); | ||
806 | if (result != 0) { | ||
807 | DBG_ERROR(et131x_dbginfo, "Can't get PCI resources\n"); | ||
808 | goto err_disable; | ||
809 | } | ||
810 | |||
811 | /* Enable PCI bus mastering */ | ||
812 | DBG_TRACE(et131x_dbginfo, "Setting PCI Bus Mastering...\n"); | ||
813 | pci_set_master(pdev); | ||
814 | |||
815 | /* Query PCI for Power Mgmt Capabilities | ||
816 | * | ||
817 | * NOTE: Now reading PowerMgmt in another location; is this still | ||
818 | * needed? | ||
819 | */ | ||
820 | pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); | ||
821 | if (pm_cap == 0) { | ||
822 | DBG_ERROR(et131x_dbginfo, | ||
823 | "Cannot find Power Management capabilities\n"); | ||
824 | result = -EIO; | ||
825 | goto err_release_res; | ||
826 | } | ||
827 | |||
828 | /* Check the DMA addressing support of this device */ | ||
829 | if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { | ||
830 | DBG_TRACE(et131x_dbginfo, "64-bit DMA addressing supported\n"); | ||
831 | pci_using_dac = true; | ||
832 | |||
833 | result = | ||
834 | pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); | ||
835 | if (result != 0) { | ||
836 | DBG_ERROR(et131x_dbginfo, | ||
837 | "Unable to obtain 64 bit DMA for consistent allocations\n"); | ||
838 | goto err_release_res; | ||
839 | } | ||
840 | } else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) { | ||
841 | DBG_TRACE(et131x_dbginfo, | ||
842 | "64-bit DMA addressing NOT supported\n"); | ||
843 | DBG_TRACE(et131x_dbginfo, | ||
844 | "32-bit DMA addressing will be used\n"); | ||
845 | pci_using_dac = false; | ||
846 | } else { | ||
847 | DBG_ERROR(et131x_dbginfo, "No usable DMA addressing method\n"); | ||
848 | result = -EIO; | ||
849 | goto err_release_res; | ||
850 | } | ||
851 | |||
852 | /* Allocate netdev and private adapter structs */ | ||
853 | DBG_TRACE(et131x_dbginfo, | ||
854 | "Allocate netdev and private adapter structs...\n"); | ||
855 | netdev = et131x_device_alloc(); | ||
856 | if (netdev == NULL) { | ||
857 | DBG_ERROR(et131x_dbginfo, "Couldn't alloc netdev struct\n"); | ||
858 | result = -ENOMEM; | ||
859 | goto err_release_res; | ||
860 | } | ||
861 | |||
862 | /* Setup the fundamental net_device and private adapter structure elements */ | ||
863 | DBG_TRACE(et131x_dbginfo, "Setting fundamental net_device info...\n"); | ||
864 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
865 | if (pci_using_dac) { | ||
866 | //netdev->features |= NETIF_F_HIGHDMA; | ||
867 | } | ||
868 | |||
869 | /* | ||
870 | * NOTE - Turn this on when we're ready to deal with SG-DMA | ||
871 | * | ||
872 | * NOTE: According to "Linux Device Drivers", 3rd ed, Rubini et al, | ||
873 | * if checksumming is not performed in HW, then the kernel will not | ||
874 | * use SG. | ||
875 | * From pp 510-511: | ||
876 | * | ||
877 | * "Note that the kernel does not perform scatter/gather I/O to your | ||
878 | * device if it does not also provide some form of checksumming as | ||
879 | * well. The reason is that, if the kernel has to make a pass over a | ||
880 | * fragmented ("nonlinear") packet to calculate the checksum, it | ||
881 | * might as well copy the data and coalesce the packet at the same | ||
882 | * time." | ||
883 | * | ||
884 | * This has been verified by setting the flags below and still not | ||
885 | * receiving a scattered buffer from the network stack, so leave it | ||
886 | * off until checksums are calculated in HW. | ||
887 | */ | ||
888 | //netdev->features |= NETIF_F_SG; | ||
889 | //netdev->features |= NETIF_F_NO_CSUM; | ||
890 | //netdev->features |= NETIF_F_LLTX; | ||
891 | |||
892 | /* Allocate private adapter struct and copy in relevant information */ | ||
893 | adapter = netdev_priv(netdev); | ||
894 | adapter->pdev = pdev; | ||
895 | adapter->netdev = netdev; | ||
896 | adapter->VendorID = pdev->vendor; | ||
897 | adapter->DeviceID = pdev->device; | ||
898 | |||
899 | /* Do the same for the netdev struct */ | ||
900 | netdev->irq = pdev->irq; | ||
901 | netdev->base_addr = pdev->resource[0].start; | ||
902 | |||
903 | /* Initialize spinlocks here */ | ||
904 | DBG_TRACE(et131x_dbginfo, "Initialize spinlocks...\n"); | ||
905 | |||
906 | spin_lock_init(&adapter->Lock); | ||
907 | spin_lock_init(&adapter->TCBSendQLock); | ||
908 | spin_lock_init(&adapter->TCBReadyQLock); | ||
909 | spin_lock_init(&adapter->SendHWLock); | ||
910 | spin_lock_init(&adapter->SendWaitLock); | ||
911 | spin_lock_init(&adapter->RcvLock); | ||
912 | spin_lock_init(&adapter->RcvPendLock); | ||
913 | spin_lock_init(&adapter->FbrLock); | ||
914 | spin_lock_init(&adapter->PHYLock); | ||
915 | |||
916 | /* Parse configuration parameters into the private adapter struct */ | ||
917 | et131x_config_parse(adapter); | ||
918 | |||
919 | /* Find the physical adapter | ||
920 | * | ||
921 | * NOTE: This is the equivalent of the MpFindAdapter() routine; can we | ||
922 | * lump it's init with the device specific init below into a | ||
923 | * single init function? | ||
924 | */ | ||
925 | //while (et131x_find_adapter(adapter, pdev) != 0); | ||
926 | et131x_find_adapter(adapter, pdev); | ||
927 | |||
928 | /* Map the bus-relative registers to system virtual memory */ | ||
929 | DBG_TRACE(et131x_dbginfo, | ||
930 | "Mapping bus-relative registers to virtual memory...\n"); | ||
931 | |||
932 | adapter->CSRAddress = ioremap_nocache(pci_resource_start(pdev, 0), | ||
933 | pci_resource_len(pdev, 0)); | ||
934 | if (adapter->CSRAddress == NULL) { | ||
935 | DBG_ERROR(et131x_dbginfo, "Cannot map device registers\n"); | ||
936 | result = -ENOMEM; | ||
937 | goto err_free_dev; | ||
938 | } | ||
939 | |||
940 | /* Perform device-specific initialization here (See code below) */ | ||
941 | |||
942 | /* If Phy COMA mode was enabled when we went down, disable it here. */ | ||
943 | { | ||
944 | PM_CSR_t GlobalPmCSR = { 0 }; | ||
945 | |||
946 | GlobalPmCSR.bits.pm_sysclk_gate = 1; | ||
947 | GlobalPmCSR.bits.pm_txclk_gate = 1; | ||
948 | GlobalPmCSR.bits.pm_rxclk_gate = 1; | ||
949 | writel(GlobalPmCSR.value, | ||
950 | &adapter->CSRAddress->global.pm_csr.value); | ||
951 | } | ||
952 | |||
953 | /* Issue a global reset to the et1310 */ | ||
954 | DBG_TRACE(et131x_dbginfo, "Issuing soft reset...\n"); | ||
955 | et131x_soft_reset(adapter); | ||
956 | |||
957 | /* Disable all interrupts (paranoid) */ | ||
958 | DBG_TRACE(et131x_dbginfo, "Disable device interrupts...\n"); | ||
959 | et131x_disable_interrupts(adapter); | ||
960 | |||
961 | /* Allocate DMA memory */ | ||
962 | result = et131x_adapter_memory_alloc(adapter); | ||
963 | if (result != 0) { | ||
964 | DBG_ERROR(et131x_dbginfo, | ||
965 | "Could not alloc adapater memory (DMA)\n"); | ||
966 | goto err_iounmap; | ||
967 | } | ||
968 | |||
969 | /* Init send data structures */ | ||
970 | DBG_TRACE(et131x_dbginfo, "Init send data structures...\n"); | ||
971 | et131x_init_send(adapter); | ||
972 | |||
973 | adapter->PoMgmt.PowerState = NdisDeviceStateD0; | ||
974 | |||
975 | /* Register the interrupt | ||
976 | * | ||
977 | * NOTE - This is being done in the open routine, where most other | ||
978 | * Linux drivers setup IRQ handlers. Make sure device | ||
979 | * interrupts are not turned on before the IRQ is registered!! | ||
980 | * | ||
981 | * What we will do here is setup the task structure for the | ||
982 | * ISR's deferred handler | ||
983 | */ | ||
984 | INIT_WORK(&adapter->task, et131x_isr_handler); | ||
985 | |||
986 | /* Determine MAC Address, and copy into the net_device struct */ | ||
987 | DBG_TRACE(et131x_dbginfo, "Retrieve MAC address...\n"); | ||
988 | et131x_setup_hardware_properties(adapter); | ||
989 | |||
990 | memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN); | ||
991 | |||
992 | /* Setup et1310 as per the documentation */ | ||
993 | DBG_TRACE(et131x_dbginfo, "Setup the adapter...\n"); | ||
994 | et131x_adapter_setup(adapter); | ||
995 | |||
996 | /* Create a timer to count errors received by the NIC */ | ||
997 | init_timer(&adapter->ErrorTimer); | ||
998 | |||
999 | adapter->ErrorTimer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000; | ||
1000 | adapter->ErrorTimer.function = et131x_error_timer_handler; | ||
1001 | adapter->ErrorTimer.data = (unsigned long)adapter; | ||
1002 | |||
1003 | /* Initialize link state */ | ||
1004 | et131x_link_detection_handler((unsigned long)adapter); | ||
1005 | |||
1006 | /* Intialize variable for counting how long we do not have link status */ | ||
1007 | adapter->PoMgmt.TransPhyComaModeOnBoot = 0; | ||
1008 | |||
1009 | /* We can enable interrupts now | ||
1010 | * | ||
1011 | * NOTE - Because registration of interrupt handler is done in the | ||
1012 | * device's open(), defer enabling device interrupts to that | ||
1013 | * point | ||
1014 | */ | ||
1015 | |||
1016 | /* Register the net_device struct with the Linux network layer */ | ||
1017 | DBG_TRACE(et131x_dbginfo, "Registering net_device...\n"); | ||
1018 | if ((result = register_netdev(netdev)) != 0) { | ||
1019 | DBG_ERROR(et131x_dbginfo, "register_netdev() failed\n"); | ||
1020 | goto err_mem_free; | ||
1021 | } | ||
1022 | |||
1023 | /* Register the net_device struct with the PCI subsystem. Save a copy | ||
1024 | * of the PCI config space for this device now that the device has | ||
1025 | * been initialized, just in case it needs to be quickly restored. | ||
1026 | */ | ||
1027 | pci_set_drvdata(pdev, netdev); | ||
1028 | |||
1029 | pci_save_state(adapter->pdev); | ||
1030 | |||
1031 | out: | ||
1032 | DBG_LEAVE(et131x_dbginfo); | ||
1033 | return result; | ||
1034 | |||
1035 | err_mem_free: | ||
1036 | et131x_adapter_memory_free(adapter); | ||
1037 | err_iounmap: | ||
1038 | iounmap(adapter->CSRAddress); | ||
1039 | err_free_dev: | ||
1040 | free_netdev(netdev); | ||
1041 | err_release_res: | ||
1042 | pci_release_regions(pdev); | ||
1043 | err_disable: | ||
1044 | pci_disable_device(pdev); | ||
1045 | goto out; | ||
1046 | } | ||
diff --git a/drivers/staging/et131x/et131x_initpci.h b/drivers/staging/et131x/et131x_initpci.h new file mode 100644 index 000000000000..bbacb6277595 --- /dev/null +++ b/drivers/staging/et131x/et131x_initpci.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_initpci.h - Header which includes common data and function prototypes | ||
12 | * related to the driver's PCI (and PCI Express) information. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef __ET131X_INITPCI_H__ | ||
60 | #define __ET131X_INITPCI_H__ | ||
61 | |||
62 | /* Function Prototypes */ | ||
63 | void et131x_align_allocated_memory(struct et131x_adapter *adapter, | ||
64 | u64 *phys_addr, | ||
65 | u64 *offset, u64 mask); | ||
66 | |||
67 | int et131x_adapter_setup(struct et131x_adapter *adapter); | ||
68 | int et131x_adapter_memory_alloc(struct et131x_adapter *adapter); | ||
69 | void et131x_adapter_memory_free(struct et131x_adapter *adapter); | ||
70 | void et131x_setup_hardware_properties(struct et131x_adapter *adapter); | ||
71 | void et131x_soft_reset(struct et131x_adapter *adapter); | ||
72 | |||
73 | #endif /* __ET131X_INITPCI_H__ */ | ||
diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c new file mode 100644 index 000000000000..00afad174a62 --- /dev/null +++ b/drivers/staging/et131x/et131x_isr.c | |||
@@ -0,0 +1,488 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_isr.c - File which contains the ISR, ISR handler, and related routines | ||
12 | * for processing interrupts from the device. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "et131x_version.h" | ||
60 | #include "et131x_debug.h" | ||
61 | #include "et131x_defs.h" | ||
62 | |||
63 | #include <linux/init.h> | ||
64 | #include <linux/module.h> | ||
65 | #include <linux/types.h> | ||
66 | #include <linux/kernel.h> | ||
67 | |||
68 | #include <linux/sched.h> | ||
69 | #include <linux/ptrace.h> | ||
70 | #include <linux/slab.h> | ||
71 | #include <linux/ctype.h> | ||
72 | #include <linux/string.h> | ||
73 | #include <linux/timer.h> | ||
74 | #include <linux/interrupt.h> | ||
75 | #include <linux/in.h> | ||
76 | #include <linux/delay.h> | ||
77 | #include <asm/io.h> | ||
78 | #include <asm/system.h> | ||
79 | #include <asm/bitops.h> | ||
80 | |||
81 | #include <linux/netdevice.h> | ||
82 | #include <linux/etherdevice.h> | ||
83 | #include <linux/skbuff.h> | ||
84 | #include <linux/if_arp.h> | ||
85 | #include <linux/ioport.h> | ||
86 | |||
87 | #include "et1310_phy.h" | ||
88 | #include "et1310_pm.h" | ||
89 | #include "et1310_jagcore.h" | ||
90 | #include "et1310_mac.h" | ||
91 | |||
92 | #include "et131x_adapter.h" | ||
93 | |||
94 | /* Data for debugging facilities */ | ||
95 | #ifdef CONFIG_ET131X_DEBUG | ||
96 | extern dbg_info_t *et131x_dbginfo; | ||
97 | #endif /* CONFIG_ET131X_DEBUG */ | ||
98 | |||
99 | /** | ||
100 | * et131x_isr - The Interrupt Service Routine for the driver. | ||
101 | * @irq: the IRQ on which the interrupt was received. | ||
102 | * @dev_id: device-specific info (here a pointer to a net_device struct) | ||
103 | * | ||
104 | * Returns a value indicating if the interrupt was handled. | ||
105 | */ | ||
106 | irqreturn_t et131x_isr(int irq, void *dev_id) | ||
107 | { | ||
108 | bool handled = true; | ||
109 | struct net_device *netdev = (struct net_device *)dev_id; | ||
110 | struct et131x_adapter *adapter = NULL; | ||
111 | INTERRUPT_t status; | ||
112 | |||
113 | if (netdev == NULL || !netif_device_present(netdev)) { | ||
114 | DBG_WARNING(et131x_dbginfo, | ||
115 | "No net_device struct or device not present\n"); | ||
116 | handled = false; | ||
117 | goto out; | ||
118 | } | ||
119 | |||
120 | adapter = netdev_priv(netdev); | ||
121 | |||
122 | /* If the adapter is in low power state, then it should not | ||
123 | * recognize any interrupt | ||
124 | */ | ||
125 | |||
126 | /* Disable Device Interrupts */ | ||
127 | et131x_disable_interrupts(adapter); | ||
128 | |||
129 | /* Get a copy of the value in the interrupt status register | ||
130 | * so we can process the interrupting section | ||
131 | */ | ||
132 | status.value = readl(&adapter->CSRAddress->global.int_status.value); | ||
133 | |||
134 | if (adapter->FlowControl == TxOnly || | ||
135 | adapter->FlowControl == Both) { | ||
136 | status.value &= ~INT_MASK_ENABLE; | ||
137 | } else { | ||
138 | status.value &= ~INT_MASK_ENABLE_NO_FLOW; | ||
139 | } | ||
140 | |||
141 | /* Make sure this is our interrupt */ | ||
142 | if (!status.value) { | ||
143 | #ifdef CONFIG_ET131X_DEBUG | ||
144 | adapter->Stats.UnhandledInterruptsPerSec++; | ||
145 | #endif | ||
146 | handled = false; | ||
147 | DBG_VERBOSE(et131x_dbginfo, "NOT OUR INTERRUPT\n"); | ||
148 | et131x_enable_interrupts(adapter); | ||
149 | goto out; | ||
150 | } | ||
151 | |||
152 | /* This is our interrupt, so process accordingly */ | ||
153 | #ifdef CONFIG_ET131X_DEBUG | ||
154 | if (status.bits.rxdma_xfr_done) { | ||
155 | adapter->Stats.RxDmaInterruptsPerSec++; | ||
156 | } | ||
157 | |||
158 | if (status.bits.txdma_isr) { | ||
159 | adapter->Stats.TxDmaInterruptsPerSec++; | ||
160 | } | ||
161 | #endif | ||
162 | |||
163 | if (status.bits.watchdog_interrupt) { | ||
164 | PMP_TCB pMpTcb = adapter->TxRing.CurrSendHead; | ||
165 | |||
166 | if (pMpTcb) { | ||
167 | if (++pMpTcb->PacketStaleCount > 1) { | ||
168 | status.bits.txdma_isr = 1; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | if (adapter->RxRing.UnfinishedReceives) { | ||
173 | status.bits.rxdma_xfr_done = 1; | ||
174 | } else if (pMpTcb == NULL) { | ||
175 | writel(0, &adapter->CSRAddress->global.watchdog_timer); | ||
176 | } | ||
177 | |||
178 | status.bits.watchdog_interrupt = 0; | ||
179 | #ifdef CONFIG_ET131X_DEBUG | ||
180 | adapter->Stats.WatchDogInterruptsPerSec++; | ||
181 | #endif | ||
182 | } | ||
183 | |||
184 | if (status.value == 0) { | ||
185 | /* This interrupt has in some way been "handled" by | ||
186 | * the ISR. Either it was a spurious Rx interrupt, or | ||
187 | * it was a Tx interrupt that has been filtered by | ||
188 | * the ISR. | ||
189 | */ | ||
190 | et131x_enable_interrupts(adapter); | ||
191 | goto out; | ||
192 | } | ||
193 | |||
194 | /* We need to save the interrupt status value for use in our | ||
195 | * DPC. We will clear the software copy of that in that | ||
196 | * routine. | ||
197 | */ | ||
198 | adapter->Stats.InterruptStatus = status; | ||
199 | |||
200 | /* Schedule the ISR handler as a bottom-half task in the | ||
201 | * kernel's tq_immediate queue, and mark the queue for | ||
202 | * execution | ||
203 | */ | ||
204 | schedule_work(&adapter->task); | ||
205 | |||
206 | out: | ||
207 | return IRQ_RETVAL(handled); | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * et131x_isr_handler - The ISR handler | ||
212 | * @p_adapter, a pointer to the device's private adapter structure | ||
213 | * | ||
214 | * scheduled to run in a deferred context by the ISR. This is where the ISR's | ||
215 | * work actually gets done. | ||
216 | */ | ||
217 | void et131x_isr_handler(struct work_struct *work) | ||
218 | { | ||
219 | struct et131x_adapter *pAdapter = | ||
220 | container_of(work, struct et131x_adapter, task); | ||
221 | INTERRUPT_t GlobStatus = pAdapter->Stats.InterruptStatus; | ||
222 | ADDRESS_MAP_t __iomem *iomem = pAdapter->CSRAddress; | ||
223 | |||
224 | /* | ||
225 | * These first two are by far the most common. Once handled, we clear | ||
226 | * their two bits in the status word. If the word is now zero, we | ||
227 | * exit. | ||
228 | */ | ||
229 | /* Handle all the completed Transmit interrupts */ | ||
230 | if (GlobStatus.bits.txdma_isr) { | ||
231 | DBG_TX(et131x_dbginfo, "TXDMA_ISR interrupt\n"); | ||
232 | et131x_handle_send_interrupt(pAdapter); | ||
233 | } | ||
234 | |||
235 | /* Handle all the completed Receives interrupts */ | ||
236 | if (GlobStatus.bits.rxdma_xfr_done) { | ||
237 | DBG_RX(et131x_dbginfo, "RXDMA_XFR_DONE interrupt\n"); | ||
238 | et131x_handle_recv_interrupt(pAdapter); | ||
239 | } | ||
240 | |||
241 | GlobStatus.value &= 0xffffffd7; | ||
242 | |||
243 | if (GlobStatus.value) { | ||
244 | /* Handle the TXDMA Error interrupt */ | ||
245 | if (GlobStatus.bits.txdma_err) { | ||
246 | TXDMA_ERROR_t TxDmaErr; | ||
247 | |||
248 | /* Following read also clears the register (COR) */ | ||
249 | TxDmaErr.value = readl(&iomem->txdma.TxDmaError.value); | ||
250 | |||
251 | DBG_WARNING(et131x_dbginfo, | ||
252 | "TXDMA_ERR interrupt, error = %d\n", | ||
253 | TxDmaErr.value); | ||
254 | } | ||
255 | |||
256 | /* Handle Free Buffer Ring 0 and 1 Low interrupt */ | ||
257 | if (GlobStatus.bits.rxdma_fb_ring0_low || | ||
258 | GlobStatus.bits.rxdma_fb_ring1_low) { | ||
259 | /* | ||
260 | * This indicates the number of unused buffers in | ||
261 | * RXDMA free buffer ring 0 is <= the limit you | ||
262 | * programmed. Free buffer resources need to be | ||
263 | * returned. Free buffers are consumed as packets | ||
264 | * are passed from the network to the host. The host | ||
265 | * becomes aware of the packets from the contents of | ||
266 | * the packet status ring. This ring is queried when | ||
267 | * the packet done interrupt occurs. Packets are then | ||
268 | * passed to the OS. When the OS is done with the | ||
269 | * packets the resources can be returned to the | ||
270 | * ET1310 for re-use. This interrupt is one method of | ||
271 | * returning resources. | ||
272 | */ | ||
273 | DBG_WARNING(et131x_dbginfo, | ||
274 | "RXDMA_FB_RING0_LOW or " | ||
275 | "RXDMA_FB_RING1_LOW interrupt\n"); | ||
276 | |||
277 | /* If the user has flow control on, then we will | ||
278 | * send a pause packet, otherwise just exit | ||
279 | */ | ||
280 | if (pAdapter->FlowControl == TxOnly || | ||
281 | pAdapter->FlowControl == Both) { | ||
282 | PM_CSR_t pm_csr; | ||
283 | |||
284 | /* Tell the device to send a pause packet via | ||
285 | * the back pressure register | ||
286 | */ | ||
287 | pm_csr.value = readl(&iomem->global.pm_csr.value); | ||
288 | if (pm_csr.bits.pm_phy_sw_coma == 0) { | ||
289 | TXMAC_BP_CTRL_t bp_ctrl = { 0 }; | ||
290 | |||
291 | bp_ctrl.bits.bp_req = 1; | ||
292 | bp_ctrl.bits.bp_xonxoff = 1; | ||
293 | writel(bp_ctrl.value, | ||
294 | &iomem->txmac.bp_ctrl.value); | ||
295 | } | ||
296 | } | ||
297 | } | ||
298 | |||
299 | /* Handle Packet Status Ring Low Interrupt */ | ||
300 | if (GlobStatus.bits.rxdma_pkt_stat_ring_low) { | ||
301 | DBG_WARNING(et131x_dbginfo, | ||
302 | "RXDMA_PKT_STAT_RING_LOW interrupt\n"); | ||
303 | |||
304 | /* | ||
305 | * Same idea as with the two Free Buffer Rings. | ||
306 | * Packets going from the network to the host each | ||
307 | * consume a free buffer resource and a packet status | ||
308 | * resource. These resoures are passed to the OS. | ||
309 | * When the OS is done with the resources, they need | ||
310 | * to be returned to the ET1310. This is one method | ||
311 | * of returning the resources. | ||
312 | */ | ||
313 | } | ||
314 | |||
315 | /* Handle RXDMA Error Interrupt */ | ||
316 | if (GlobStatus.bits.rxdma_err) { | ||
317 | /* | ||
318 | * The rxdma_error interrupt is sent when a time-out | ||
319 | * on a request issued by the JAGCore has occurred or | ||
320 | * a completion is returned with an un-successful | ||
321 | * status. In both cases the request is considered | ||
322 | * complete. The JAGCore will automatically re-try the | ||
323 | * request in question. Normally information on events | ||
324 | * like these are sent to the host using the "Advanced | ||
325 | * Error Reporting" capability. This interrupt is | ||
326 | * another way of getting similar information. The | ||
327 | * only thing required is to clear the interrupt by | ||
328 | * reading the ISR in the global resources. The | ||
329 | * JAGCore will do a re-try on the request. Normally | ||
330 | * you should never see this interrupt. If you start | ||
331 | * to see this interrupt occurring frequently then | ||
332 | * something bad has occurred. A reset might be the | ||
333 | * thing to do. | ||
334 | */ | ||
335 | // TRAP(); | ||
336 | |||
337 | pAdapter->TxMacTest.value = | ||
338 | readl(&iomem->txmac.tx_test.value); | ||
339 | DBG_WARNING(et131x_dbginfo, | ||
340 | "RxDMA_ERR interrupt, error %x\n", | ||
341 | pAdapter->TxMacTest.value); | ||
342 | } | ||
343 | |||
344 | /* Handle the Wake on LAN Event */ | ||
345 | if (GlobStatus.bits.wake_on_lan) { | ||
346 | /* | ||
347 | * This is a secondary interrupt for wake on LAN. | ||
348 | * The driver should never see this, if it does, | ||
349 | * something serious is wrong. We will TRAP the | ||
350 | * message when we are in DBG mode, otherwise we | ||
351 | * will ignore it. | ||
352 | */ | ||
353 | DBG_ERROR(et131x_dbginfo, "WAKE_ON_LAN interrupt\n"); | ||
354 | } | ||
355 | |||
356 | /* Handle the PHY interrupt */ | ||
357 | if (GlobStatus.bits.phy_interrupt) { | ||
358 | PM_CSR_t pm_csr; | ||
359 | MI_BMSR_t BmsrInts, BmsrData; | ||
360 | MI_ISR_t myIsr; | ||
361 | |||
362 | DBG_VERBOSE(et131x_dbginfo, "PHY interrupt\n"); | ||
363 | |||
364 | /* If we are in coma mode when we get this interrupt, | ||
365 | * we need to disable it. | ||
366 | */ | ||
367 | pm_csr.value = readl(&iomem->global.pm_csr.value); | ||
368 | if (pm_csr.bits.pm_phy_sw_coma == 1) { | ||
369 | /* | ||
370 | * Check to see if we are in coma mode and if | ||
371 | * so, disable it because we will not be able | ||
372 | * to read PHY values until we are out. | ||
373 | */ | ||
374 | DBG_VERBOSE(et131x_dbginfo, | ||
375 | "Device is in COMA mode, " | ||
376 | "need to wake up\n"); | ||
377 | DisablePhyComa(pAdapter); | ||
378 | } | ||
379 | |||
380 | /* Read the PHY ISR to clear the reason for the | ||
381 | * interrupt. | ||
382 | */ | ||
383 | MiRead(pAdapter, (uint8_t) offsetof(MI_REGS_t, isr), | ||
384 | &myIsr.value); | ||
385 | |||
386 | if (!pAdapter->ReplicaPhyLoopbk) { | ||
387 | MiRead(pAdapter, | ||
388 | (uint8_t) offsetof(MI_REGS_t, bmsr), | ||
389 | &BmsrData.value); | ||
390 | |||
391 | BmsrInts.value = | ||
392 | pAdapter->Bmsr.value ^ BmsrData.value; | ||
393 | pAdapter->Bmsr.value = BmsrData.value; | ||
394 | |||
395 | DBG_VERBOSE(et131x_dbginfo, | ||
396 | "Bmsr.value = 0x%04x," | ||
397 | "Bmsr_ints.value = 0x%04x\n", | ||
398 | BmsrData.value, BmsrInts.value); | ||
399 | |||
400 | /* Do all the cable in / cable out stuff */ | ||
401 | et131x_Mii_check(pAdapter, BmsrData, BmsrInts); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | /* Let's move on to the TxMac */ | ||
406 | if (GlobStatus.bits.txmac_interrupt) { | ||
407 | pAdapter->TxRing.TxMacErr.value = | ||
408 | readl(&iomem->txmac.err.value); | ||
409 | |||
410 | /* | ||
411 | * When any of the errors occur and TXMAC generates | ||
412 | * an interrupt to report these errors, it usually | ||
413 | * means that TXMAC has detected an error in the data | ||
414 | * stream retrieved from the on-chip Tx Q. All of | ||
415 | * these errors are catastrophic and TXMAC won't be | ||
416 | * able to recover data when these errors occur. In | ||
417 | * a nutshell, the whole Tx path will have to be reset | ||
418 | * and re-configured afterwards. | ||
419 | */ | ||
420 | DBG_WARNING(et131x_dbginfo, | ||
421 | "TXMAC interrupt, error 0x%08x\n", | ||
422 | pAdapter->TxRing.TxMacErr.value); | ||
423 | |||
424 | /* If we are debugging, we want to see this error, | ||
425 | * otherwise we just want the device to be reset and | ||
426 | * continue | ||
427 | */ | ||
428 | //DBG_TRAP(); | ||
429 | } | ||
430 | |||
431 | /* Handle RXMAC Interrupt */ | ||
432 | if (GlobStatus.bits.rxmac_interrupt) { | ||
433 | /* | ||
434 | * These interrupts are catastrophic to the device, | ||
435 | * what we need to do is disable the interrupts and | ||
436 | * set the flag to cause us to reset so we can solve | ||
437 | * this issue. | ||
438 | */ | ||
439 | // MP_SET_FLAG( pAdapter, fMP_ADAPTER_HARDWARE_ERROR ); | ||
440 | |||
441 | DBG_WARNING(et131x_dbginfo, | ||
442 | "RXMAC interrupt, error 0x%08x. Requesting reset\n", | ||
443 | readl(&iomem->rxmac.err_reg.value)); | ||
444 | |||
445 | DBG_WARNING(et131x_dbginfo, | ||
446 | "Enable 0x%08x, Diag 0x%08x\n", | ||
447 | readl(&iomem->rxmac.ctrl.value), | ||
448 | readl(&iomem->rxmac.rxq_diag.value)); | ||
449 | |||
450 | /* | ||
451 | * If we are debugging, we want to see this error, | ||
452 | * otherwise we just want the device to be reset and | ||
453 | * continue | ||
454 | */ | ||
455 | // TRAP(); | ||
456 | } | ||
457 | |||
458 | /* Handle MAC_STAT Interrupt */ | ||
459 | if (GlobStatus.bits.mac_stat_interrupt) { | ||
460 | /* | ||
461 | * This means at least one of the un-masked counters | ||
462 | * in the MAC_STAT block has rolled over. Use this | ||
463 | * to maintain the top, software managed bits of the | ||
464 | * counter(s). | ||
465 | */ | ||
466 | DBG_VERBOSE(et131x_dbginfo, "MAC_STAT interrupt\n"); | ||
467 | HandleMacStatInterrupt(pAdapter); | ||
468 | } | ||
469 | |||
470 | /* Handle SLV Timeout Interrupt */ | ||
471 | if (GlobStatus.bits.slv_timeout) { | ||
472 | /* | ||
473 | * This means a timeout has occured on a read or | ||
474 | * write request to one of the JAGCore registers. The | ||
475 | * Global Resources block has terminated the request | ||
476 | * and on a read request, returned a "fake" value. | ||
477 | * The most likely reasons are: Bad Address or the | ||
478 | * addressed module is in a power-down state and | ||
479 | * can't respond. | ||
480 | */ | ||
481 | DBG_VERBOSE(et131x_dbginfo, "SLV_TIMEOUT interrupt\n"); | ||
482 | } | ||
483 | } | ||
484 | |||
485 | if (pAdapter->PoMgmt.PowerState == NdisDeviceStateD0) { | ||
486 | et131x_enable_interrupts(pAdapter); | ||
487 | } | ||
488 | } | ||
diff --git a/drivers/staging/et131x/et131x_isr.h b/drivers/staging/et131x/et131x_isr.h new file mode 100644 index 000000000000..76a51d56551e --- /dev/null +++ b/drivers/staging/et131x/et131x_isr.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_isr.h - Defines, structs, enums, prototypes, etc. pertaining to the | ||
12 | * ISR processing code. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef __ET131X_ISR_H__ | ||
60 | #define __ET131X_ISR_H__ | ||
61 | |||
62 | irqreturn_t et131x_isr(int irq, void *dev_id); | ||
63 | void et131x_isr_handler(struct work_struct *work); | ||
64 | |||
65 | #endif /* __ET131X_ISR_H__ */ | ||
diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c new file mode 100644 index 000000000000..de65972ff362 --- /dev/null +++ b/drivers/staging/et131x/et131x_netdev.c | |||
@@ -0,0 +1,856 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_netdev.c - Routines and data required by all Linux network devices. | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include "et131x_version.h" | ||
59 | #include "et131x_debug.h" | ||
60 | #include "et131x_defs.h" | ||
61 | |||
62 | #include <linux/init.h> | ||
63 | #include <linux/module.h> | ||
64 | #include <linux/types.h> | ||
65 | #include <linux/kernel.h> | ||
66 | |||
67 | #include <linux/sched.h> | ||
68 | #include <linux/ptrace.h> | ||
69 | #include <linux/slab.h> | ||
70 | #include <linux/ctype.h> | ||
71 | #include <linux/string.h> | ||
72 | #include <linux/timer.h> | ||
73 | #include <linux/interrupt.h> | ||
74 | #include <linux/in.h> | ||
75 | #include <linux/delay.h> | ||
76 | #include <asm/io.h> | ||
77 | #include <asm/system.h> | ||
78 | #include <asm/bitops.h> | ||
79 | |||
80 | #include <linux/mii.h> | ||
81 | #include <linux/netdevice.h> | ||
82 | #include <linux/etherdevice.h> | ||
83 | #include <linux/skbuff.h> | ||
84 | #include <linux/if_arp.h> | ||
85 | #include <linux/ioport.h> | ||
86 | |||
87 | #include "et1310_phy.h" | ||
88 | #include "et1310_pm.h" | ||
89 | #include "et1310_jagcore.h" | ||
90 | #include "et1310_mac.h" | ||
91 | #include "et1310_tx.h" | ||
92 | |||
93 | #include "et131x_adapter.h" | ||
94 | #include "et131x_isr.h" | ||
95 | #include "et131x_initpci.h" | ||
96 | |||
97 | /* Data for debugging facilities */ | ||
98 | #ifdef CONFIG_ET131X_DEBUG | ||
99 | extern dbg_info_t *et131x_dbginfo; | ||
100 | #endif /* CONFIG_ET131X_DEBUG */ | ||
101 | |||
102 | struct net_device_stats *et131x_stats(struct net_device *netdev); | ||
103 | int et131x_open(struct net_device *netdev); | ||
104 | int et131x_close(struct net_device *netdev); | ||
105 | int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd); | ||
106 | void et131x_multicast(struct net_device *netdev); | ||
107 | int et131x_tx(struct sk_buff *skb, struct net_device *netdev); | ||
108 | void et131x_tx_timeout(struct net_device *netdev); | ||
109 | int et131x_change_mtu(struct net_device *netdev, int new_mtu); | ||
110 | int et131x_set_mac_addr(struct net_device *netdev, void *new_mac); | ||
111 | void et131x_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); | ||
112 | void et131x_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); | ||
113 | void et131x_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); | ||
114 | |||
115 | /** | ||
116 | * et131x_device_alloc | ||
117 | * | ||
118 | * Returns pointer to the allocated and initialized net_device struct for | ||
119 | * this device. | ||
120 | * | ||
121 | * Create instances of net_device and wl_private for the new adapter and | ||
122 | * register the device's entry points in the net_device structure. | ||
123 | */ | ||
124 | struct net_device *et131x_device_alloc(void) | ||
125 | { | ||
126 | struct net_device *netdev; | ||
127 | |||
128 | DBG_ENTER(et131x_dbginfo); | ||
129 | |||
130 | /* Alloc net_device and adapter structs */ | ||
131 | netdev = alloc_etherdev(sizeof(struct et131x_adapter)); | ||
132 | |||
133 | if (netdev == NULL) { | ||
134 | DBG_ERROR(et131x_dbginfo, | ||
135 | "Alloc of net_device struct failed\n"); | ||
136 | DBG_LEAVE(et131x_dbginfo); | ||
137 | return NULL; | ||
138 | } | ||
139 | |||
140 | /* Setup the function registration table (and other data) for a | ||
141 | * net_device | ||
142 | */ | ||
143 | //netdev->init = &et131x_init; | ||
144 | //netdev->set_config = &et131x_config; | ||
145 | netdev->get_stats = &et131x_stats; | ||
146 | netdev->open = &et131x_open; | ||
147 | netdev->stop = &et131x_close; | ||
148 | netdev->do_ioctl = &et131x_ioctl; | ||
149 | netdev->set_multicast_list = &et131x_multicast; | ||
150 | netdev->hard_start_xmit = &et131x_tx; | ||
151 | netdev->tx_timeout = &et131x_tx_timeout; | ||
152 | netdev->watchdog_timeo = ET131X_TX_TIMEOUT; | ||
153 | netdev->change_mtu = &et131x_change_mtu; | ||
154 | netdev->set_mac_address = &et131x_set_mac_addr; | ||
155 | |||
156 | //netdev->ethtool_ops = &et131x_ethtool_ops; | ||
157 | |||
158 | // Poll? | ||
159 | //netdev->poll = &et131x_poll; | ||
160 | //netdev->poll_controller = &et131x_poll_controller; | ||
161 | |||
162 | DBG_LEAVE(et131x_dbginfo); | ||
163 | return netdev; | ||
164 | } | ||
165 | |||
166 | /** | ||
167 | * et131x_stats - Return the current device statistics. | ||
168 | * @netdev: device whose stats are being queried | ||
169 | * | ||
170 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
171 | */ | ||
172 | struct net_device_stats *et131x_stats(struct net_device *netdev) | ||
173 | { | ||
174 | struct et131x_adapter *adapter = netdev_priv(netdev); | ||
175 | struct net_device_stats *stats = &adapter->net_stats; | ||
176 | CE_STATS_t *devstat = &adapter->Stats; | ||
177 | |||
178 | DBG_ENTER(et131x_dbginfo); | ||
179 | |||
180 | stats->rx_packets = devstat->ipackets; | ||
181 | stats->tx_packets = devstat->opackets; | ||
182 | stats->rx_errors = devstat->length_err + devstat->alignment_err + | ||
183 | devstat->crc_err + devstat->code_violations + devstat->other_errors; | ||
184 | stats->tx_errors = devstat->max_pkt_error; | ||
185 | stats->multicast = devstat->multircv; | ||
186 | stats->collisions = devstat->collisions; | ||
187 | |||
188 | stats->rx_length_errors = devstat->length_err; | ||
189 | stats->rx_over_errors = devstat->rx_ov_flow; | ||
190 | stats->rx_crc_errors = devstat->crc_err; | ||
191 | |||
192 | // NOTE: These stats don't have corresponding values in CE_STATS, so we're | ||
193 | // going to have to update these directly from within the TX/RX code | ||
194 | //stats->rx_bytes = 20; //devstat->; | ||
195 | //stats->tx_bytes = 20; //devstat->; | ||
196 | //stats->rx_dropped = devstat->; | ||
197 | //stats->tx_dropped = devstat->; | ||
198 | |||
199 | // NOTE: Not used, can't find analogous statistics | ||
200 | //stats->rx_frame_errors = devstat->; | ||
201 | //stats->rx_fifo_errors = devstat->; | ||
202 | //stats->rx_missed_errors = devstat->; | ||
203 | |||
204 | //stats->tx_aborted_errors = devstat->; | ||
205 | //stats->tx_carrier_errors = devstat->; | ||
206 | //stats->tx_fifo_errors = devstat->; | ||
207 | //stats->tx_heartbeat_errors = devstat->; | ||
208 | //stats->tx_window_errors = devstat->; | ||
209 | |||
210 | DBG_LEAVE(et131x_dbginfo); | ||
211 | return stats; | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * et131x_open - Open the device for use. | ||
216 | * @netdev: device to be opened | ||
217 | * | ||
218 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
219 | */ | ||
220 | int et131x_open(struct net_device *netdev) | ||
221 | { | ||
222 | int result = 0; | ||
223 | struct et131x_adapter *adapter = netdev_priv(netdev); | ||
224 | |||
225 | DBG_ENTER(et131x_dbginfo); | ||
226 | |||
227 | /* Start the timer to track NIC errors */ | ||
228 | add_timer(&adapter->ErrorTimer); | ||
229 | |||
230 | /* Register our ISR */ | ||
231 | DBG_TRACE(et131x_dbginfo, "Registering ISR...\n"); | ||
232 | |||
233 | result = | ||
234 | request_irq(netdev->irq, et131x_isr, IRQF_SHARED, netdev->name, | ||
235 | netdev); | ||
236 | if (result) { | ||
237 | DBG_ERROR(et131x_dbginfo, "Could not register ISR\n"); | ||
238 | DBG_LEAVE(et131x_dbginfo); | ||
239 | return result; | ||
240 | } | ||
241 | |||
242 | /* Enable the Tx and Rx DMA engines (if not already enabled) */ | ||
243 | et131x_rx_dma_enable(adapter); | ||
244 | et131x_tx_dma_enable(adapter); | ||
245 | |||
246 | /* Enable device interrupts */ | ||
247 | et131x_enable_interrupts(adapter); | ||
248 | |||
249 | MP_SET_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE); | ||
250 | |||
251 | /* We're ready to move some data, so start the queue */ | ||
252 | netif_start_queue(netdev); | ||
253 | |||
254 | DBG_LEAVE(et131x_dbginfo); | ||
255 | return result; | ||
256 | } | ||
257 | |||
258 | /** | ||
259 | * et131x_close - Close the device | ||
260 | * @netdev: device to be closed | ||
261 | * | ||
262 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
263 | */ | ||
264 | int et131x_close(struct net_device *netdev) | ||
265 | { | ||
266 | struct et131x_adapter *adapter = netdev_priv(netdev); | ||
267 | |||
268 | DBG_ENTER(et131x_dbginfo); | ||
269 | |||
270 | /* First thing is to stop the queue */ | ||
271 | netif_stop_queue(netdev); | ||
272 | |||
273 | /* Stop the Tx and Rx DMA engines */ | ||
274 | et131x_rx_dma_disable(adapter); | ||
275 | et131x_tx_dma_disable(adapter); | ||
276 | |||
277 | /* Disable device interrupts */ | ||
278 | et131x_disable_interrupts(adapter); | ||
279 | |||
280 | /* Deregistering ISR */ | ||
281 | MP_CLEAR_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE); | ||
282 | |||
283 | DBG_TRACE(et131x_dbginfo, "Deregistering ISR...\n"); | ||
284 | free_irq(netdev->irq, netdev); | ||
285 | |||
286 | /* Stop the error timer */ | ||
287 | del_timer_sync(&adapter->ErrorTimer); | ||
288 | |||
289 | DBG_LEAVE(et131x_dbginfo); | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | /** | ||
294 | * et131x_ioctl_mii - The function which handles MII IOCTLs | ||
295 | * @netdev: device on which the query is being made | ||
296 | * @reqbuf: the request-specific data buffer | ||
297 | * @cmd: the command request code | ||
298 | * | ||
299 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
300 | */ | ||
301 | int et131x_ioctl_mii(struct net_device *netdev, struct ifreq *reqbuf, int cmd) | ||
302 | { | ||
303 | int status = 0; | ||
304 | struct et131x_adapter *pAdapter = netdev_priv(netdev); | ||
305 | struct mii_ioctl_data *data = if_mii(reqbuf); | ||
306 | |||
307 | DBG_ENTER(et131x_dbginfo); | ||
308 | |||
309 | switch (cmd) { | ||
310 | case SIOCGMIIPHY: | ||
311 | DBG_VERBOSE(et131x_dbginfo, "SIOCGMIIPHY\n"); | ||
312 | data->phy_id = pAdapter->Stats.xcvr_addr; | ||
313 | break; | ||
314 | |||
315 | case SIOCGMIIREG: | ||
316 | DBG_VERBOSE(et131x_dbginfo, "SIOCGMIIREG\n"); | ||
317 | if (!capable(CAP_NET_ADMIN)) { | ||
318 | status = -EPERM; | ||
319 | } else { | ||
320 | status = MiRead(pAdapter, | ||
321 | data->reg_num, &data->val_out); | ||
322 | } | ||
323 | break; | ||
324 | |||
325 | case SIOCSMIIREG: | ||
326 | DBG_VERBOSE(et131x_dbginfo, "SIOCSMIIREG\n"); | ||
327 | if (!capable(CAP_NET_ADMIN)) { | ||
328 | status = -EPERM; | ||
329 | } else { | ||
330 | status = MiWrite(pAdapter, data->reg_num, | ||
331 | data->val_in); | ||
332 | } | ||
333 | break; | ||
334 | |||
335 | default: | ||
336 | status = -EOPNOTSUPP; | ||
337 | } | ||
338 | |||
339 | DBG_LEAVE(et131x_dbginfo); | ||
340 | return status; | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * et131x_ioctl - The I/O Control handler for the driver | ||
345 | * @netdev: device on which the control request is being made | ||
346 | * @reqbuf: a pointer to the IOCTL request buffer | ||
347 | * @cmd: the IOCTL command code | ||
348 | * | ||
349 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
350 | */ | ||
351 | int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd) | ||
352 | { | ||
353 | int status = 0; | ||
354 | |||
355 | DBG_ENTER(et131x_dbginfo); | ||
356 | |||
357 | switch (cmd) { | ||
358 | case SIOCGMIIPHY: | ||
359 | case SIOCGMIIREG: | ||
360 | case SIOCSMIIREG: | ||
361 | status = et131x_ioctl_mii(netdev, reqbuf, cmd); | ||
362 | break; | ||
363 | |||
364 | default: | ||
365 | DBG_WARNING(et131x_dbginfo, "Unhandled IOCTL Code: 0x%04x\n", | ||
366 | cmd); | ||
367 | status = -EOPNOTSUPP; | ||
368 | } | ||
369 | |||
370 | DBG_LEAVE(et131x_dbginfo); | ||
371 | return status; | ||
372 | } | ||
373 | |||
374 | /** | ||
375 | * et131x_set_packet_filter - Configures the Rx Packet filtering on the device | ||
376 | * @adapter: pointer to our private adapter structure | ||
377 | * | ||
378 | * Returns 0 on success, errno on failure | ||
379 | */ | ||
380 | int et131x_set_packet_filter(struct et131x_adapter *adapter) | ||
381 | { | ||
382 | int status = 0; | ||
383 | uint32_t filter = adapter->PacketFilter; | ||
384 | RXMAC_CTRL_t ctrl; | ||
385 | RXMAC_PF_CTRL_t pf_ctrl; | ||
386 | |||
387 | DBG_ENTER(et131x_dbginfo); | ||
388 | |||
389 | ctrl.value = readl(&adapter->CSRAddress->rxmac.ctrl.value); | ||
390 | pf_ctrl.value = readl(&adapter->CSRAddress->rxmac.pf_ctrl.value); | ||
391 | |||
392 | /* Default to disabled packet filtering. Enable it in the individual | ||
393 | * case statements that require the device to filter something | ||
394 | */ | ||
395 | ctrl.bits.pkt_filter_disable = 1; | ||
396 | |||
397 | /* Set us to be in promiscuous mode so we receive everything, this | ||
398 | * is also true when we get a packet filter of 0 | ||
399 | */ | ||
400 | if ((filter & ET131X_PACKET_TYPE_PROMISCUOUS) || filter == 0) { | ||
401 | pf_ctrl.bits.filter_broad_en = 0; | ||
402 | pf_ctrl.bits.filter_multi_en = 0; | ||
403 | pf_ctrl.bits.filter_uni_en = 0; | ||
404 | } else { | ||
405 | /* | ||
406 | * Set us up with Multicast packet filtering. Three cases are | ||
407 | * possible - (1) we have a multi-cast list, (2) we receive ALL | ||
408 | * multicast entries or (3) we receive none. | ||
409 | */ | ||
410 | if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST) { | ||
411 | DBG_VERBOSE(et131x_dbginfo, | ||
412 | "Multicast filtering OFF (Rx ALL MULTICAST)\n"); | ||
413 | pf_ctrl.bits.filter_multi_en = 0; | ||
414 | } else { | ||
415 | DBG_VERBOSE(et131x_dbginfo, "Multicast filtering ON\n"); | ||
416 | SetupDeviceForMulticast(adapter); | ||
417 | pf_ctrl.bits.filter_multi_en = 1; | ||
418 | ctrl.bits.pkt_filter_disable = 0; | ||
419 | } | ||
420 | |||
421 | /* Set us up with Unicast packet filtering */ | ||
422 | if (filter & ET131X_PACKET_TYPE_DIRECTED) { | ||
423 | DBG_VERBOSE(et131x_dbginfo, "Unicast Filtering ON\n"); | ||
424 | SetupDeviceForUnicast(adapter); | ||
425 | pf_ctrl.bits.filter_uni_en = 1; | ||
426 | ctrl.bits.pkt_filter_disable = 0; | ||
427 | } | ||
428 | |||
429 | /* Set us up with Broadcast packet filtering */ | ||
430 | if (filter & ET131X_PACKET_TYPE_BROADCAST) { | ||
431 | DBG_VERBOSE(et131x_dbginfo, "Broadcast Filtering ON\n"); | ||
432 | pf_ctrl.bits.filter_broad_en = 1; | ||
433 | ctrl.bits.pkt_filter_disable = 0; | ||
434 | } else { | ||
435 | DBG_VERBOSE(et131x_dbginfo, | ||
436 | "Broadcast Filtering OFF\n"); | ||
437 | pf_ctrl.bits.filter_broad_en = 0; | ||
438 | } | ||
439 | |||
440 | /* Setup the receive mac configuration registers - Packet | ||
441 | * Filter control + the enable / disable for packet filter | ||
442 | * in the control reg. | ||
443 | */ | ||
444 | writel(pf_ctrl.value, | ||
445 | &adapter->CSRAddress->rxmac.pf_ctrl.value); | ||
446 | writel(ctrl.value, &adapter->CSRAddress->rxmac.ctrl.value); | ||
447 | } | ||
448 | |||
449 | DBG_LEAVE(et131x_dbginfo); | ||
450 | return status; | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * et131x_multicast - The handler to configure multicasting on the interface | ||
455 | * @netdev: a pointer to a net_device struct representing the device | ||
456 | */ | ||
457 | void et131x_multicast(struct net_device *netdev) | ||
458 | { | ||
459 | struct et131x_adapter *adapter = netdev_priv(netdev); | ||
460 | uint32_t PacketFilter = 0; | ||
461 | uint32_t count; | ||
462 | unsigned long lockflags; | ||
463 | struct dev_mc_list *mclist = netdev->mc_list; | ||
464 | |||
465 | DBG_ENTER(et131x_dbginfo); | ||
466 | |||
467 | spin_lock_irqsave(&adapter->Lock, lockflags); | ||
468 | |||
469 | /* Before we modify the platform-independent filter flags, store them | ||
470 | * locally. This allows us to determine if anything's changed and if | ||
471 | * we even need to bother the hardware | ||
472 | */ | ||
473 | PacketFilter = adapter->PacketFilter; | ||
474 | |||
475 | /* Clear the 'multicast' flag locally; becuase we only have a single | ||
476 | * flag to check multicast, and multiple multicast addresses can be | ||
477 | * set, this is the easiest way to determine if more than one | ||
478 | * multicast address is being set. | ||
479 | */ | ||
480 | PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST; | ||
481 | |||
482 | /* Check the net_device flags and set the device independent flags | ||
483 | * accordingly | ||
484 | */ | ||
485 | DBG_VERBOSE(et131x_dbginfo, | ||
486 | "MULTICAST ADDR COUNT: %d\n", netdev->mc_count); | ||
487 | |||
488 | if (netdev->flags & IFF_PROMISC) { | ||
489 | DBG_VERBOSE(et131x_dbginfo, "Request: PROMISCUOUS MODE ON\n"); | ||
490 | adapter->PacketFilter |= ET131X_PACKET_TYPE_PROMISCUOUS; | ||
491 | } else { | ||
492 | DBG_VERBOSE(et131x_dbginfo, "Request: PROMISCUOUS MODE OFF\n"); | ||
493 | adapter->PacketFilter &= ~ET131X_PACKET_TYPE_PROMISCUOUS; | ||
494 | } | ||
495 | |||
496 | if (netdev->flags & IFF_ALLMULTI) { | ||
497 | DBG_VERBOSE(et131x_dbginfo, "Request: ACCEPT ALL MULTICAST\n"); | ||
498 | adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST; | ||
499 | } | ||
500 | |||
501 | if (netdev->mc_count > NIC_MAX_MCAST_LIST) { | ||
502 | DBG_WARNING(et131x_dbginfo, | ||
503 | "ACCEPT ALL MULTICAST for now, as there's more Multicast " | ||
504 | "addresses than the HW supports\n"); | ||
505 | |||
506 | adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST; | ||
507 | } | ||
508 | |||
509 | if (netdev->mc_count < 1) { | ||
510 | DBG_VERBOSE(et131x_dbginfo, "Request: REJECT ALL MULTICAST\n"); | ||
511 | adapter->PacketFilter &= ~ET131X_PACKET_TYPE_ALL_MULTICAST; | ||
512 | adapter->PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST; | ||
513 | } else { | ||
514 | DBG_VERBOSE(et131x_dbginfo, | ||
515 | "Request: SET MULTICAST FILTER(S)\n"); | ||
516 | adapter->PacketFilter |= ET131X_PACKET_TYPE_MULTICAST; | ||
517 | } | ||
518 | |||
519 | /* Set values in the private adapter struct */ | ||
520 | adapter->MCAddressCount = netdev->mc_count; | ||
521 | |||
522 | if (netdev->mc_count) { | ||
523 | if (mclist->dmi_addrlen != ETH_ALEN) { | ||
524 | DBG_WARNING(et131x_dbginfo, | ||
525 | "Multicast addrs are not ETH_ALEN in size\n"); | ||
526 | } else { | ||
527 | count = netdev->mc_count - 1; | ||
528 | memcpy(adapter->MCList[count], mclist->dmi_addr, | ||
529 | ETH_ALEN); | ||
530 | } | ||
531 | } | ||
532 | |||
533 | /* Are the new flags different from the previous ones? If not, then no | ||
534 | * action is required | ||
535 | * | ||
536 | * NOTE - This block will always update the MCList with the hardware, | ||
537 | * even if the addresses aren't the same. | ||
538 | */ | ||
539 | if (PacketFilter != adapter->PacketFilter) { | ||
540 | /* Call the device's filter function */ | ||
541 | DBG_VERBOSE(et131x_dbginfo, "UPDATE REQUIRED, FLAGS changed\n"); | ||
542 | |||
543 | et131x_set_packet_filter(adapter); | ||
544 | } else { | ||
545 | DBG_VERBOSE(et131x_dbginfo, | ||
546 | "NO UPDATE REQUIRED, FLAGS didn't change\n"); | ||
547 | } | ||
548 | |||
549 | spin_unlock_irqrestore(&adapter->Lock, lockflags); | ||
550 | |||
551 | DBG_LEAVE(et131x_dbginfo); | ||
552 | } | ||
553 | |||
554 | /** | ||
555 | * et131x_tx - The handler to tx a packet on the device | ||
556 | * @skb: data to be Tx'd | ||
557 | * @netdev: device on which data is to be Tx'd | ||
558 | * | ||
559 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
560 | */ | ||
561 | int et131x_tx(struct sk_buff *skb, struct net_device *netdev) | ||
562 | { | ||
563 | int status = 0; | ||
564 | |||
565 | DBG_TX_ENTER(et131x_dbginfo); | ||
566 | |||
567 | /* Save the timestamp for the TX timeout watchdog */ | ||
568 | netdev->trans_start = jiffies; | ||
569 | |||
570 | /* Call the device-specific data Tx routine */ | ||
571 | status = et131x_send_packets(skb, netdev); | ||
572 | |||
573 | /* Check status and manage the netif queue if necessary */ | ||
574 | if (status != 0) { | ||
575 | if (status == -ENOMEM) { | ||
576 | DBG_VERBOSE(et131x_dbginfo, | ||
577 | "OUT OF TCBs; STOP NETIF QUEUE\n"); | ||
578 | |||
579 | /* Put the queue to sleep until resources are | ||
580 | * available | ||
581 | */ | ||
582 | netif_stop_queue(netdev); | ||
583 | status = 1; | ||
584 | } else { | ||
585 | DBG_WARNING(et131x_dbginfo, | ||
586 | "Misc error; drop packet\n"); | ||
587 | status = 0; | ||
588 | } | ||
589 | } | ||
590 | |||
591 | DBG_TX_LEAVE(et131x_dbginfo); | ||
592 | return status; | ||
593 | } | ||
594 | |||
595 | /** | ||
596 | * et131x_tx_timeout - Timeout handler | ||
597 | * @netdev: a pointer to a net_device struct representing the device | ||
598 | * | ||
599 | * The handler called when a Tx request times out. The timeout period is | ||
600 | * specified by the 'tx_timeo" element in the net_device structure (see | ||
601 | * et131x_alloc_device() to see how this value is set). | ||
602 | */ | ||
603 | void et131x_tx_timeout(struct net_device *netdev) | ||
604 | { | ||
605 | struct et131x_adapter *pAdapter = netdev_priv(netdev); | ||
606 | PMP_TCB pMpTcb; | ||
607 | unsigned long lockflags; | ||
608 | |||
609 | DBG_WARNING(et131x_dbginfo, "TX TIMEOUT\n"); | ||
610 | |||
611 | /* Just skip this part if the adapter is doing link detection */ | ||
612 | if (MP_TEST_FLAG(pAdapter, fMP_ADAPTER_LINK_DETECTION)) { | ||
613 | DBG_ERROR(et131x_dbginfo, "Still doing link detection\n"); | ||
614 | return; | ||
615 | } | ||
616 | |||
617 | /* Any nonrecoverable hardware error? | ||
618 | * Checks adapter->flags for any failure in phy reading | ||
619 | */ | ||
620 | if (MP_TEST_FLAG(pAdapter, fMP_ADAPTER_NON_RECOVER_ERROR)) { | ||
621 | DBG_WARNING(et131x_dbginfo, "Non recoverable error - remove\n"); | ||
622 | return; | ||
623 | } | ||
624 | |||
625 | /* Hardware failure? */ | ||
626 | if (MP_TEST_FLAG(pAdapter, fMP_ADAPTER_HARDWARE_ERROR)) { | ||
627 | DBG_WARNING(et131x_dbginfo, "hardware error - reset\n"); | ||
628 | return; | ||
629 | } | ||
630 | |||
631 | /* Is send stuck? */ | ||
632 | spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags); | ||
633 | |||
634 | pMpTcb = pAdapter->TxRing.CurrSendHead; | ||
635 | |||
636 | if (pMpTcb != NULL) { | ||
637 | pMpTcb->Count++; | ||
638 | |||
639 | if (pMpTcb->Count > NIC_SEND_HANG_THRESHOLD) { | ||
640 | #ifdef CONFIG_ET131X_DEBUG | ||
641 | TX_STATUS_BLOCK_t txDmaComplete = | ||
642 | *(pAdapter->TxRing.pTxStatusVa); | ||
643 | PTX_DESC_ENTRY_t pDesc = | ||
644 | pAdapter->TxRing.pTxDescRingVa + | ||
645 | pMpTcb->WrIndex.bits.val; | ||
646 | #endif | ||
647 | TX_DESC_ENTRY_t StuckDescriptors[10]; | ||
648 | |||
649 | if (pMpTcb->WrIndex.bits.val > 7) { | ||
650 | memcpy(StuckDescriptors, | ||
651 | pAdapter->TxRing.pTxDescRingVa + | ||
652 | pMpTcb->WrIndex.bits.val - 6, | ||
653 | sizeof(TX_DESC_ENTRY_t) * 10); | ||
654 | } | ||
655 | |||
656 | spin_unlock_irqrestore(&pAdapter->TCBSendQLock, | ||
657 | lockflags); | ||
658 | |||
659 | DBG_WARNING(et131x_dbginfo, | ||
660 | "Send stuck - reset. pMpTcb->WrIndex %x, Flags 0x%08x\n", | ||
661 | pMpTcb->WrIndex.bits.val, | ||
662 | pMpTcb->Flags); | ||
663 | |||
664 | DBG_WARNING(et131x_dbginfo, | ||
665 | "pDesc 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", | ||
666 | pDesc->DataBufferPtrHigh, | ||
667 | pDesc->DataBufferPtrLow, pDesc->word2.value, | ||
668 | pDesc->word3.value); | ||
669 | |||
670 | DBG_WARNING(et131x_dbginfo, | ||
671 | "WbStatus 0x%08x\n", txDmaComplete.value); | ||
672 | |||
673 | #ifdef CONFIG_ET131X_DEBUG | ||
674 | DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 0); | ||
675 | DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 1); | ||
676 | DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 3); | ||
677 | DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 5); | ||
678 | #endif | ||
679 | et131x_close(netdev); | ||
680 | et131x_open(netdev); | ||
681 | |||
682 | return; | ||
683 | } | ||
684 | } | ||
685 | |||
686 | spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags); | ||
687 | } | ||
688 | |||
689 | /** | ||
690 | * et131x_change_mtu - The handler called to change the MTU for the device | ||
691 | * @netdev: device whose MTU is to be changed | ||
692 | * @new_mtu: the desired MTU | ||
693 | * | ||
694 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
695 | */ | ||
696 | int et131x_change_mtu(struct net_device *netdev, int new_mtu) | ||
697 | { | ||
698 | int result = 0; | ||
699 | struct et131x_adapter *adapter = netdev_priv(netdev); | ||
700 | |||
701 | DBG_ENTER(et131x_dbginfo); | ||
702 | |||
703 | /* Make sure the requested MTU is valid */ | ||
704 | if (new_mtu == 0 || new_mtu > 9216) { | ||
705 | DBG_LEAVE(et131x_dbginfo); | ||
706 | return -EINVAL; | ||
707 | } | ||
708 | |||
709 | /* Stop the netif queue */ | ||
710 | netif_stop_queue(netdev); | ||
711 | |||
712 | /* Stop the Tx and Rx DMA engines */ | ||
713 | et131x_rx_dma_disable(adapter); | ||
714 | et131x_tx_dma_disable(adapter); | ||
715 | |||
716 | /* Disable device interrupts */ | ||
717 | et131x_disable_interrupts(adapter); | ||
718 | et131x_handle_send_interrupt(adapter); | ||
719 | et131x_handle_recv_interrupt(adapter); | ||
720 | |||
721 | /* Set the new MTU */ | ||
722 | netdev->mtu = new_mtu; | ||
723 | |||
724 | /* Free Rx DMA memory */ | ||
725 | et131x_adapter_memory_free(adapter); | ||
726 | |||
727 | /* Set the config parameter for Jumbo Packet support */ | ||
728 | adapter->RegistryJumboPacket = new_mtu + 14; | ||
729 | et131x_soft_reset(adapter); | ||
730 | |||
731 | /* Alloc and init Rx DMA memory */ | ||
732 | result = et131x_adapter_memory_alloc(adapter); | ||
733 | if (result != 0) { | ||
734 | DBG_WARNING(et131x_dbginfo, | ||
735 | "Change MTU failed; couldn't re-alloc DMA memory\n"); | ||
736 | return result; | ||
737 | } | ||
738 | |||
739 | et131x_init_send(adapter); | ||
740 | |||
741 | et131x_setup_hardware_properties(adapter); | ||
742 | memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN); | ||
743 | |||
744 | /* Init the device with the new settings */ | ||
745 | et131x_adapter_setup(adapter); | ||
746 | |||
747 | /* Enable interrupts */ | ||
748 | if (MP_TEST_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE)) { | ||
749 | et131x_enable_interrupts(adapter); | ||
750 | } | ||
751 | |||
752 | /* Restart the Tx and Rx DMA engines */ | ||
753 | et131x_rx_dma_enable(adapter); | ||
754 | et131x_tx_dma_enable(adapter); | ||
755 | |||
756 | /* Restart the netif queue */ | ||
757 | netif_wake_queue(netdev); | ||
758 | |||
759 | DBG_LEAVE(et131x_dbginfo); | ||
760 | return result; | ||
761 | } | ||
762 | |||
763 | /** | ||
764 | * et131x_set_mac_addr - handler to change the MAC address for the device | ||
765 | * @netdev: device whose MAC is to be changed | ||
766 | * @new_mac: the desired MAC address | ||
767 | * | ||
768 | * Returns 0 on success, errno on failure (as defined in errno.h) | ||
769 | * | ||
770 | * IMPLEMENTED BY : blux http://berndlux.de 22.01.2007 21:14 | ||
771 | */ | ||
772 | int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) | ||
773 | { | ||
774 | int result = 0; | ||
775 | struct et131x_adapter *adapter = netdev_priv(netdev); | ||
776 | struct sockaddr *address = new_mac; | ||
777 | |||
778 | DBG_ENTER(et131x_dbginfo); | ||
779 | // begin blux | ||
780 | // DBG_VERBOSE( et131x_dbginfo, "Function not implemented!!\n" ); | ||
781 | |||
782 | if (adapter == NULL) { | ||
783 | DBG_LEAVE(et131x_dbginfo); | ||
784 | return -ENODEV; | ||
785 | } | ||
786 | |||
787 | /* Make sure the requested MAC is valid */ | ||
788 | if (!is_valid_ether_addr(address->sa_data)) { | ||
789 | DBG_LEAVE(et131x_dbginfo); | ||
790 | return -EINVAL; | ||
791 | } | ||
792 | |||
793 | /* Stop the netif queue */ | ||
794 | netif_stop_queue(netdev); | ||
795 | |||
796 | /* Stop the Tx and Rx DMA engines */ | ||
797 | et131x_rx_dma_disable(adapter); | ||
798 | et131x_tx_dma_disable(adapter); | ||
799 | |||
800 | /* Disable device interrupts */ | ||
801 | et131x_disable_interrupts(adapter); | ||
802 | et131x_handle_send_interrupt(adapter); | ||
803 | et131x_handle_recv_interrupt(adapter); | ||
804 | |||
805 | /* Set the new MAC */ | ||
806 | // netdev->set_mac_address = &new_mac; | ||
807 | // netdev->mtu = new_mtu; | ||
808 | |||
809 | memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len); | ||
810 | |||
811 | printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
812 | netdev->name, netdev->dev_addr[0], netdev->dev_addr[1], | ||
813 | netdev->dev_addr[2], netdev->dev_addr[3], netdev->dev_addr[4], | ||
814 | netdev->dev_addr[5]); | ||
815 | |||
816 | /* Free Rx DMA memory */ | ||
817 | et131x_adapter_memory_free(adapter); | ||
818 | |||
819 | /* Set the config parameter for Jumbo Packet support */ | ||
820 | // adapter->RegistryJumboPacket = new_mtu + 14; | ||
821 | // blux: not needet here, w'll change the MAC | ||
822 | |||
823 | et131x_soft_reset(adapter); | ||
824 | |||
825 | /* Alloc and init Rx DMA memory */ | ||
826 | result = et131x_adapter_memory_alloc(adapter); | ||
827 | if (result != 0) { | ||
828 | DBG_WARNING(et131x_dbginfo, | ||
829 | "Change MAC failed; couldn't re-alloc DMA memory\n"); | ||
830 | return result; | ||
831 | } | ||
832 | |||
833 | et131x_init_send(adapter); | ||
834 | |||
835 | et131x_setup_hardware_properties(adapter); | ||
836 | // memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); | ||
837 | // blux: no, do not override our nice address | ||
838 | |||
839 | /* Init the device with the new settings */ | ||
840 | et131x_adapter_setup(adapter); | ||
841 | |||
842 | /* Enable interrupts */ | ||
843 | if (MP_TEST_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE)) { | ||
844 | et131x_enable_interrupts(adapter); | ||
845 | } | ||
846 | |||
847 | /* Restart the Tx and Rx DMA engines */ | ||
848 | et131x_rx_dma_enable(adapter); | ||
849 | et131x_tx_dma_enable(adapter); | ||
850 | |||
851 | /* Restart the netif queue */ | ||
852 | netif_wake_queue(netdev); | ||
853 | |||
854 | DBG_LEAVE(et131x_dbginfo); | ||
855 | return result; | ||
856 | } | ||
diff --git a/drivers/staging/et131x/et131x_netdev.h b/drivers/staging/et131x/et131x_netdev.h new file mode 100644 index 000000000000..b8acd14ff830 --- /dev/null +++ b/drivers/staging/et131x/et131x_netdev.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_netdev.h - Defines, structs, enums, prototypes, etc. related to the | ||
12 | * driver's net_device support. | ||
13 | * | ||
14 | *------------------------------------------------------------------------------ | ||
15 | * | ||
16 | * SOFTWARE LICENSE | ||
17 | * | ||
18 | * This software is provided subject to the following terms and conditions, | ||
19 | * which you should read carefully before using the software. Using this | ||
20 | * software indicates your acceptance of these terms and conditions. If you do | ||
21 | * not agree with these terms and conditions, do not use the software. | ||
22 | * | ||
23 | * Copyright © 2005 Agere Systems Inc. | ||
24 | * All rights reserved. | ||
25 | * | ||
26 | * Redistribution and use in source or binary forms, with or without | ||
27 | * modifications, are permitted provided that the following conditions are met: | ||
28 | * | ||
29 | * . Redistributions of source code must retain the above copyright notice, this | ||
30 | * list of conditions and the following Disclaimer as comments in the code as | ||
31 | * well as in the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
35 | * this list of conditions and the following Disclaimer in the documentation | ||
36 | * and/or other materials provided with the distribution. | ||
37 | * | ||
38 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
39 | * may be used to endorse or promote products derived from this software | ||
40 | * without specific prior written permission. | ||
41 | * | ||
42 | * Disclaimer | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
45 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
46 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
47 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
48 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
50 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
52 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
54 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
55 | * DAMAGE. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef __ET131X_NETDEV_H__ | ||
60 | #define __ET131X_NETDEV_H__ | ||
61 | |||
62 | struct net_device *et131x_device_alloc(void); | ||
63 | |||
64 | #endif /* __ET131X_NETDEV_H__ */ | ||
diff --git a/drivers/staging/et131x/et131x_version.h b/drivers/staging/et131x/et131x_version.h new file mode 100644 index 000000000000..2ea645e1066e --- /dev/null +++ b/drivers/staging/et131x/et131x_version.h | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * Agere Systems Inc. | ||
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | ||
4 | * | ||
5 | * Copyright © 2005 Agere Systems Inc. | ||
6 | * All rights reserved. | ||
7 | * http://www.agere.com | ||
8 | * | ||
9 | *------------------------------------------------------------------------------ | ||
10 | * | ||
11 | * et131x_version.h - This file provides system and device version information. | ||
12 | * | ||
13 | *------------------------------------------------------------------------------ | ||
14 | * | ||
15 | * SOFTWARE LICENSE | ||
16 | * | ||
17 | * This software is provided subject to the following terms and conditions, | ||
18 | * which you should read carefully before using the software. Using this | ||
19 | * software indicates your acceptance of these terms and conditions. If you do | ||
20 | * not agree with these terms and conditions, do not use the software. | ||
21 | * | ||
22 | * Copyright © 2005 Agere Systems Inc. | ||
23 | * All rights reserved. | ||
24 | * | ||
25 | * Redistribution and use in source or binary forms, with or without | ||
26 | * modifications, are permitted provided that the following conditions are met: | ||
27 | * | ||
28 | * . Redistributions of source code must retain the above copyright notice, this | ||
29 | * list of conditions and the following Disclaimer as comments in the code as | ||
30 | * well as in the documentation and/or other materials provided with the | ||
31 | * distribution. | ||
32 | * | ||
33 | * . Redistributions in binary form must reproduce the above copyright notice, | ||
34 | * this list of conditions and the following Disclaimer in the documentation | ||
35 | * and/or other materials provided with the distribution. | ||
36 | * | ||
37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | ||
38 | * may be used to endorse or promote products derived from this software | ||
39 | * without specific prior written permission. | ||
40 | * | ||
41 | * Disclaimer | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF | ||
45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | ||
46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | ||
47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | ||
48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | ||
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
54 | * DAMAGE. | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #ifndef __ET131X_VERSION_H__ | ||
59 | #define __ET131X_VERSION_H__ | ||
60 | |||
61 | #define DRIVER_AUTHOR "Victor Soriano (vjsoriano@agere.com)" | ||
62 | #define DRIVER_LICENSE "Dual BSD/GPL" | ||
63 | #define DRIVER_DEVICE_STRING "ET1310" | ||
64 | #define DRIVER_NAME "et131x" | ||
65 | #define DRIVER_MAJOR_VERSION 1 | ||
66 | #define DRIVER_MINOR_VERSION 2 | ||
67 | #define DRIVER_PATCH_VERSION 3 | ||
68 | #define DRIVER_VERSION_STRING "1.2.3" | ||
69 | #define DRIVER_VENDOR "Agere Systems, http://www.agere.com" | ||
70 | #define DRIVER_DESC "10/100/1000 Base-T Ethernet Driver" | ||
71 | |||
72 | #define STRUCT_MODULE "net" /* blux: missed by the kernel */ | ||
73 | |||
74 | #define DRIVER_INFO DRIVER_DESC " for the "\ | ||
75 | DRIVER_DEVICE_STRING ", v" \ | ||
76 | DRIVER_VERSION_STRING " by " \ | ||
77 | DRIVER_VENDOR | ||
78 | |||
79 | #define DRIVER_NAME_EXT "et131x.ko" | ||
80 | |||
81 | #endif /* __ET131X_VERSION_H__ */ | ||