File: | obj-scan-build/../linux/src/drivers/net/eepro.c |
Location: | line 430, column 5 |
Description: | Assigned value is garbage or undefined |
1 | /* eepro.c: Intel EtherExpress Pro/10 device driver for Linux. */ | |||
2 | /* | |||
3 | Written 1994-1998 by Bao C. Ha. | |||
4 | ||||
5 | Copyright (C) 1994-1998 by Bao C. Ha. | |||
6 | ||||
7 | This software may be used and distributed | |||
8 | according to the terms of the GNU Public License, | |||
9 | incorporated herein by reference. | |||
10 | ||||
11 | The author may be reached at bao@hacom.net | |||
12 | or Hacom, 2477 Wrightsboro Rd., Augusta, GA 30904. | |||
13 | ||||
14 | Things remaining to do: | |||
15 | Better record keeping of errors. | |||
16 | Eliminate transmit interrupt to reduce overhead. | |||
17 | Implement "concurrent processing". I won't be doing it! | |||
18 | ||||
19 | Bugs: | |||
20 | ||||
21 | If you have a problem of not detecting the 82595 during a | |||
22 | reboot (warm reset), disable the FLASH memory should fix it. | |||
23 | This is a compatibility hardware problem. | |||
24 | ||||
25 | Versions: | |||
26 | ||||
27 | 0.10c Some cosmetic changes. (9/28/98, BCH) | |||
28 | ||||
29 | 0.10b Should work now with (some) Pro/10+. At least for | |||
30 | me (and my two cards) it does. _No_ guarantee for | |||
31 | function with non-Pro/10+ cards! (don't have any) | |||
32 | (RMC, 9/11/96) | |||
33 | ||||
34 | 0.10 Added support for the Etherexpress Pro/10+. The | |||
35 | IRQ map was changed significantly from the old | |||
36 | pro/10. The new interrupt map was provided by | |||
37 | Rainer M. Canavan (Canavan@Zeus.cs.bonn.edu). | |||
38 | (BCH, 9/3/96) | |||
39 | ||||
40 | 0.09 Fixed a race condition in the transmit algorithm, | |||
41 | which causes crashes under heavy load with fast | |||
42 | pentium computers. The performance should also | |||
43 | improve a bit. The size of RX buffer, and hence | |||
44 | TX buffer, can also be changed via lilo or insmod. | |||
45 | (BCH, 7/31/96) | |||
46 | ||||
47 | 0.08 Implement 32-bit I/O for the 82595TX and 82595FX | |||
48 | based lan cards. Disable full-duplex mode if TPE | |||
49 | is not used. (BCH, 4/8/96) | |||
50 | ||||
51 | 0.07a Fix a stat report which counts every packet as a | |||
52 | heart-beat failure. (BCH, 6/3/95) | |||
53 | ||||
54 | 0.07 Modified to support all other 82595-based lan cards. | |||
55 | The IRQ vector of the EtherExpress Pro will be set | |||
56 | according to the value saved in the EEPROM. For other | |||
57 | cards, I will do autoirq_request() to grab the next | |||
58 | available interrupt vector. (BCH, 3/17/95) | |||
59 | ||||
60 | 0.06a,b Interim released. Minor changes in the comments and | |||
61 | print out format. (BCH, 3/9/95 and 3/14/95) | |||
62 | ||||
63 | 0.06 First stable release that I am comfortable with. (BCH, | |||
64 | 3/2/95) | |||
65 | ||||
66 | 0.05 Complete testing of multicast. (BCH, 2/23/95) | |||
67 | ||||
68 | 0.04 Adding multicast support. (BCH, 2/14/95) | |||
69 | ||||
70 | 0.03 First widely alpha release for public testing. | |||
71 | (BCH, 2/14/95) | |||
72 | ||||
73 | */ | |||
74 | ||||
75 | static const char *version = | |||
76 | "eepro.c: v0.10c 9/28/98 Bao C. Ha (bao@hacom.net)\n"; | |||
77 | ||||
78 | #include <linux/module.h> | |||
79 | ||||
80 | /* | |||
81 | Sources: | |||
82 | ||||
83 | This driver wouldn't have been written without the availability | |||
84 | of the Crynwr's Lan595 driver source code. It helps me to | |||
85 | familiarize with the 82595 chipset while waiting for the Intel | |||
86 | documentation. I also learned how to detect the 82595 using | |||
87 | the packet driver's technique. | |||
88 | ||||
89 | This driver is written by cutting and pasting the skeleton.c driver | |||
90 | provided by Donald Becker. I also borrowed the EEPROM routine from | |||
91 | Donald Becker's 82586 driver. | |||
92 | ||||
93 | Datasheet for the Intel 82595 (including the TX and FX version). It | |||
94 | provides just enough info that the casual reader might think that it | |||
95 | documents the i82595. | |||
96 | ||||
97 | The User Manual for the 82595. It provides a lot of the missing | |||
98 | information. | |||
99 | ||||
100 | */ | |||
101 | ||||
102 | #include <linux/kernel.h> | |||
103 | #include <linux/sched.h> | |||
104 | #include <linux/types.h> | |||
105 | #include <linux/fcntl.h> | |||
106 | #include <linux/interrupt.h> | |||
107 | #include <linux/ptrace.h> | |||
108 | #include <linux/ioport.h> | |||
109 | #include <linux/in.h> | |||
110 | #include <linux/malloc.h> | |||
111 | #include <linux/string.h> | |||
112 | #include <asm/system.h> | |||
113 | #include <asm/bitops.h> | |||
114 | #include <asm/io.h> | |||
115 | #include <asm/dma.h> | |||
116 | #include <linux/errno.h> | |||
117 | ||||
118 | #include <linux/netdevice.h> | |||
119 | #include <linux/etherdevice.h> | |||
120 | #include <linux/skbuff.h> | |||
121 | ||||
122 | /* First, a few definitions that the brave might change. */ | |||
123 | ||||
124 | /* A zero-terminated list of I/O addresses to be probed. */ | |||
125 | static unsigned int eepro_portlist[] = | |||
126 | { 0x300, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0}; | |||
127 | ||||
128 | /* use 0 for production, 1 for verification, >2 for debug */ | |||
129 | ||||
130 | #ifndef NET_DEBUG1 | |||
131 | #define NET_DEBUG1 1 | |||
132 | #endif | |||
133 | ||||
134 | static unsigned int net_debug = NET_DEBUG1; | |||
135 | ||||
136 | /* The number of low I/O ports used by the ethercard. */ | |||
137 | ||||
138 | #define EEPRO_IO_EXTENT16 16 | |||
139 | ||||
140 | /* Different 82595 chips */ | |||
141 | ||||
142 | #define LAN5950 0 | |||
143 | #define LAN595TX1 1 | |||
144 | #define LAN595FX2 2 | |||
145 | ||||
146 | /* Information that need to be kept for each board. */ | |||
147 | struct eepro_local { | |||
148 | struct enet_statistics stats; | |||
149 | unsigned rx_start; | |||
150 | unsigned tx_start; /* start of the transmit chain */ | |||
151 | int tx_last; /* pointer to last packet in the transmit chain */ | |||
152 | unsigned tx_end; /* end of the transmit chain (plus 1) */ | |||
153 | int eepro; /* 1 for the EtherExpress Pro/10, | |||
154 | 2 for the EtherExpress Pro/10+, | |||
155 | 0 for other 82595-based lan cards. */ | |||
156 | int version; /* a flag to indicate if this is a TX or FX | |||
157 | version of the 82595 chip. */ | |||
158 | int stepping; | |||
159 | }; | |||
160 | ||||
161 | /* The station (ethernet) address prefix, used for IDing the board. */ | |||
162 | ||||
163 | #define SA_ADDR00x00 0x00 /* Etherexpress Pro/10 */ | |||
164 | #define SA_ADDR10xaa 0xaa | |||
165 | #define SA_ADDR20x00 0x00 | |||
166 | ||||
167 | #define SA2_ADDR00x00 0x00 /* Etherexpress Pro/10+ */ | |||
168 | #define SA2_ADDR10xa0 0xa0 | |||
169 | #define SA2_ADDR20xc9 0xc9 | |||
170 | ||||
171 | #define SA3_ADDR00x00 0x00 /* more Etherexpress Pro/10+ */ | |||
172 | #define SA3_ADDR10xaa 0xaa | |||
173 | #define SA3_ADDR20x00 0x00 | |||
174 | #define SA3_ADDR30xc9 0xc9 | |||
175 | ||||
176 | /* Index to functions, as function prototypes. */ | |||
177 | ||||
178 | extern int eepro_probe(struct devicelinux_device *dev); | |||
179 | ||||
180 | static int eepro_probe1(struct devicelinux_device *dev, short ioaddr); | |||
181 | static int eepro_open(struct devicelinux_device *dev); | |||
182 | static int eepro_send_packet(struct sk_buff *skb, struct devicelinux_device *dev); | |||
183 | static void eepro_interrupt(int irq, void *dev_id, struct pt_regs *regs); | |||
184 | static void eepro_rx(struct devicelinux_device *dev); | |||
185 | static void eepro_transmit_interrupt(struct devicelinux_device *dev); | |||
186 | static int eepro_close(struct devicelinux_device *dev); | |||
187 | static struct enet_statistics *eepro_get_stats(struct devicelinux_device *dev); | |||
188 | static void set_multicast_list(struct devicelinux_device *dev); | |||
189 | ||||
190 | static int read_eeprom(int ioaddr, int location); | |||
191 | static void hardware_send_packet(struct devicelinux_device *dev, void *buf, short length); | |||
192 | static int eepro_grab_irq(struct devicelinux_device *dev); | |||
193 | ||||
194 | /* | |||
195 | Details of the i82595. | |||
196 | ||||
197 | You will need either the datasheet or the user manual to understand what | |||
198 | is going on here. The 82595 is very different from the 82586, 82593. | |||
199 | ||||
200 | The receive algorithm in eepro_rx() is just an implementation of the | |||
201 | RCV ring structure that the Intel 82595 imposes at the hardware level. | |||
202 | The receive buffer is set at 24K, and the transmit buffer is 8K. I | |||
203 | am assuming that the total buffer memory is 32K, which is true for the | |||
204 | Intel EtherExpress Pro/10. If it is less than that on a generic card, | |||
205 | the driver will be broken. | |||
206 | ||||
207 | The transmit algorithm in the hardware_send_packet() is similar to the | |||
208 | one in the eepro_rx(). The transmit buffer is a ring linked list. | |||
209 | I just queue the next available packet to the end of the list. In my | |||
210 | system, the 82595 is so fast that the list seems to always contain a | |||
211 | single packet. In other systems with faster computers and more congested | |||
212 | network traffics, the ring linked list should improve performance by | |||
213 | allowing up to 8K worth of packets to be queued. | |||
214 | ||||
215 | The sizes of the receive and transmit buffers can now be changed via lilo | |||
216 | or insmod. Lilo uses the appended line "ether=io,irq,debug,rx-buffer,eth0" | |||
217 | where rx-buffer is in KB unit. Modules uses the parameter mem which is | |||
218 | also in KB unit, for example "insmod io=io-address irq=0 mem=rx-buffer." | |||
219 | The receive buffer has to be more than 3K or less than 29K. Otherwise, | |||
220 | it is reset to the default of 24K, and, hence, 8K for the trasnmit | |||
221 | buffer (transmit-buffer = 32K - receive-buffer). | |||
222 | ||||
223 | */ | |||
224 | ||||
225 | #define RAM_SIZE0x8000 0x8000 | |||
226 | #define RCV_HEADER8 8 | |||
227 | #define RCV_RAM0x6000 0x6000 /* 24KB default for RCV buffer */ | |||
228 | #define RCV_LOWER_LIMIT0x00 0x00 /* 0x0000 */ | |||
229 | ||||
230 | /* #define RCV_UPPER_LIMIT ((RCV_RAM - 2) >> 8) */ /* 0x5ffe */ | |||
231 | #define RCV_UPPER_LIMIT(((rcv_ram) - 2) >> 8) (((rcv_ram) - 2) >> 8) | |||
232 | ||||
233 | /* #define XMT_RAM (RAM_SIZE - RCV_RAM) */ /* 8KB for XMT buffer */ | |||
234 | #define XMT_RAM(0x8000 - (rcv_ram)) (RAM_SIZE0x8000 - (rcv_ram)) /* 8KB for XMT buffer */ | |||
235 | ||||
236 | /* #define XMT_LOWER_LIMIT (RCV_RAM >> 8) */ /* 0x6000 */ | |||
237 | #define XMT_LOWER_LIMIT((rcv_ram) >> 8) ((rcv_ram) >> 8) | |||
238 | #define XMT_UPPER_LIMIT((0x8000 - 2) >> 8) ((RAM_SIZE0x8000 - 2) >> 8) /* 0x7ffe */ | |||
239 | #define XMT_HEADER8 8 | |||
240 | ||||
241 | #define RCV_DONE0x0008 0x0008 | |||
242 | #define RX_OK0x2000 0x2000 | |||
243 | #define RX_ERROR0x0d81 0x0d81 | |||
244 | ||||
245 | #define TX_DONE_BIT0x0080 0x0080 | |||
246 | #define CHAIN_BIT0x8000 0x8000 | |||
247 | #define XMT_STATUS0x02 0x02 | |||
248 | #define XMT_CHAIN0x04 0x04 | |||
249 | #define XMT_COUNT0x06 0x06 | |||
250 | ||||
251 | #define BANK0_SELECT0x00 0x00 | |||
252 | #define BANK1_SELECT0x40 0x40 | |||
253 | #define BANK2_SELECT0x80 0x80 | |||
254 | ||||
255 | /* Bank 0 registers */ | |||
256 | ||||
257 | #define COMMAND_REG0x00 0x00 /* Register 0 */ | |||
258 | #define MC_SETUP0x03 0x03 | |||
259 | #define XMT_CMD0x04 0x04 | |||
260 | #define DIAGNOSE_CMD0x07 0x07 | |||
261 | #define RCV_ENABLE_CMD0x08 0x08 | |||
262 | #define RCV_DISABLE_CMD0x0a 0x0a | |||
263 | #define STOP_RCV_CMD0x0b 0x0b | |||
264 | #define RESET_CMD0x0e 0x0e | |||
265 | #define POWER_DOWN_CMD0x18 0x18 | |||
266 | #define RESUME_XMT_CMD0x1c 0x1c | |||
267 | #define SEL_RESET_CMD0x1e 0x1e | |||
268 | #define STATUS_REG0x01 0x01 /* Register 1 */ | |||
269 | #define RX_INT0x02 0x02 | |||
270 | #define TX_INT0x04 0x04 | |||
271 | #define EXEC_STATUS0x30 0x30 | |||
272 | #define ID_REG0x02 0x02 /* Register 2 */ | |||
273 | #define R_ROBIN_BITS0xc0 0xc0 /* round robin counter */ | |||
274 | #define ID_REG_MASK0x2c 0x2c | |||
275 | #define ID_REG_SIG0x24 0x24 | |||
276 | #define AUTO_ENABLE0x10 0x10 | |||
277 | #define INT_MASK_REG0x03 0x03 /* Register 3 */ | |||
278 | #define RX_STOP_MASK0x01 0x01 | |||
279 | #define RX_MASK0x02 0x02 | |||
280 | #define TX_MASK0x04 0x04 | |||
281 | #define EXEC_MASK0x08 0x08 | |||
282 | #define ALL_MASK0x0f 0x0f | |||
283 | #define IO_32_BIT0x10 0x10 | |||
284 | #define RCV_BAR0x04 0x04 /* The following are word (16-bit) registers */ | |||
285 | #define RCV_STOP0x06 0x06 | |||
286 | #define XMT_BAR0x0a 0x0a | |||
287 | #define HOST_ADDRESS_REG0x0c 0x0c | |||
288 | #define IO_PORT0x0e 0x0e | |||
289 | #define IO_PORT_32_BIT0x0c 0x0c | |||
290 | ||||
291 | /* Bank 1 registers */ | |||
292 | ||||
293 | #define REG10x01 0x01 | |||
294 | #define WORD_WIDTH0x02 0x02 | |||
295 | #define INT_ENABLE0x80 0x80 | |||
296 | #define INT_NO_REG0x02 0x02 | |||
297 | #define RCV_LOWER_LIMIT_REG0x08 0x08 | |||
298 | #define RCV_UPPER_LIMIT_REG0x09 0x09 | |||
299 | #define XMT_LOWER_LIMIT_REG0x0a 0x0a | |||
300 | #define XMT_UPPER_LIMIT_REG0x0b 0x0b | |||
301 | ||||
302 | /* Bank 2 registers */ | |||
303 | ||||
304 | #define XMT_Chain_Int0x20 0x20 /* Interrupt at the end of the transmit chain */ | |||
305 | #define XMT_Chain_ErrStop0x40 0x40 /* Interrupt at the end of the chain even if there are errors */ | |||
306 | #define RCV_Discard_BadFrame0x80 0x80 /* Throw bad frames away, and continue to receive others */ | |||
307 | #define REG20x02 0x02 | |||
308 | #define PRMSC_Mode0x01 0x01 | |||
309 | #define Multi_IA0x20 0x20 | |||
310 | #define REG30x03 0x03 | |||
311 | #define TPE_BIT0x04 0x04 | |||
312 | #define BNC_BIT0x20 0x20 | |||
313 | #define REG130x0d 0x0d | |||
314 | #define FDX0x00 0x00 | |||
315 | #define A_N_ENABLE0x02 0x02 | |||
316 | ||||
317 | #define I_ADD_REG00x04 0x04 | |||
318 | #define I_ADD_REG10x05 0x05 | |||
319 | #define I_ADD_REG20x06 0x06 | |||
320 | #define I_ADD_REG30x07 0x07 | |||
321 | #define I_ADD_REG40x08 0x08 | |||
322 | #define I_ADD_REG50x09 0x09 | |||
323 | ||||
324 | #define EEPROM_REG0x0a 0x0a | |||
325 | #define EESK0x01 0x01 | |||
326 | #define EECS0x02 0x02 | |||
327 | #define EEDI0x04 0x04 | |||
328 | #define EEDO0x08 0x08 | |||
329 | ||||
330 | /* Check for a network adaptor of this type, and return '0' if one exists. | |||
331 | ||||
332 | If dev->base_addr == 0, probe all likely locations. | |||
333 | If dev->base_addr == 1, always return failure. | |||
334 | If dev->base_addr == 2, allocate space for the device and return success | |||
335 | (detachable devices only). | |||
336 | ||||
337 | */ | |||
338 | ||||
339 | #ifdef HAVE_DEVLIST | |||
340 | ||||
341 | /* Support for a alternate probe manager, which will eliminate the | |||
342 | boilerplate below. */ | |||
343 | ||||
344 | struct netdev_entry netcard_drv = | |||
345 | {"eepro", eepro_probe1, EEPRO_IO_EXTENT16, eepro_portlist}; | |||
346 | ||||
347 | #else | |||
348 | ||||
349 | int | |||
350 | eepro_probe(struct devicelinux_device *dev) | |||
351 | { | |||
352 | int i; | |||
353 | int base_addr = dev ? dev->base_addr : 0; | |||
| ||||
354 | ||||
355 | if (base_addr > 0x1ff) /* Check a single specified location. */ | |||
356 | return eepro_probe1(dev, base_addr); | |||
357 | else if (base_addr != 0) /* Don't probe at all. */ | |||
358 | return ENXIO6; | |||
359 | ||||
360 | for (i = 0; eepro_portlist[i]; i++) { | |||
361 | int ioaddr = eepro_portlist[i]; | |||
362 | if (check_region(ioaddr, EEPRO_IO_EXTENT16)) | |||
363 | continue; | |||
364 | ||||
365 | if (eepro_probe1(dev, ioaddr) == 0) | |||
366 | return 0; | |||
367 | } | |||
368 | ||||
369 | return ENODEV19; | |||
370 | } | |||
371 | #endif | |||
372 | ||||
373 | /* This is the real probe routine. Linux has a history of friendly device | |||
374 | probes on the ISA bus. A good device probes avoids doing writes, and | |||
375 | verifies that the correct device exists and functions. */ | |||
376 | ||||
377 | int | |||
378 | eepro_probe1(struct devicelinux_device *dev, short ioaddr) | |||
379 | { | |||
380 | unsigned short station_addr[6], id, counter; | |||
381 | int i; | |||
382 | int eepro; | |||
383 | const char *ifmap[] = {"AUI", "10Base2", "10BaseT"}; | |||
384 | enum iftype { AUI=0, BNC=1, TPE=2 }; | |||
385 | ||||
386 | /* Now, we are going to check for the signature of the | |||
387 | ID_REG (register 2 of bank 0) */ | |||
388 | if (((id=inb(ioaddr + ID_REG)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __inbc(ioaddr + 0x02) : __inb(ioaddr + 0x02))) & ID_REG_MASK0x2c) == ID_REG_SIG0x24) { | |||
389 | ||||
390 | /* We seem to have the 82595 signature, let's | |||
391 | play with its counter (last 2 bits of | |||
392 | register 2 of bank 0) to be sure. */ | |||
393 | ||||
394 | counter = (id & R_ROBIN_BITS0xc0); | |||
395 | if (((id=inb(ioaddr+ID_REG)((__builtin_constant_p((ioaddr+0x02)) && (ioaddr+0x02 ) < 256) ? __inbc(ioaddr+0x02) : __inb(ioaddr+0x02))) & R_ROBIN_BITS0xc0) == | |||
396 | (counter + 0x40)) { | |||
397 | ||||
398 | /* Yes, the 82595 has been found */ | |||
399 | ||||
400 | /* Now, get the ethernet hardware address from | |||
401 | the EEPROM */ | |||
402 | ||||
403 | station_addr[0] = read_eeprom(ioaddr, 2); | |||
404 | station_addr[1] = read_eeprom(ioaddr, 3); | |||
405 | station_addr[2] = read_eeprom(ioaddr, 4); | |||
406 | ||||
407 | /* Check the station address for the manufacturer's code */ | |||
408 | ||||
409 | if ((station_addr[2] == 0x00aa) && (station_addr[1]!= 0x00c9)) { | |||
410 | eepro = 1; | |||
411 | printk("%s: Intel EtherExpress Pro/10 ISA at %#x,", | |||
412 | dev->name, ioaddr); | |||
413 | } else | |||
414 | if ( (station_addr[2] == 0x00a0) | |||
415 | || ((station_addr[2] == 0x00aa) && (station_addr[1] == 0x00c9) )) { | |||
416 | eepro = 2; | |||
417 | printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", | |||
418 | dev->name, ioaddr); | |||
419 | } | |||
420 | else { | |||
421 | eepro = 0; | |||
422 | printk("%s: Intel 82595-based lan card at %#x,", | |||
423 | dev->name, ioaddr); | |||
424 | } | |||
425 | ||||
426 | /* Fill in the 'dev' fields. */ | |||
427 | dev->base_addr = ioaddr; | |||
428 | ||||
429 | for (i=0; i < 6; i++) { | |||
430 | dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i]; | |||
| ||||
431 | printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]); | |||
432 | } | |||
433 | ||||
434 | if ((dev->mem_end & 0x3f) < 3 || /* RX buffer must be more than 3K */ | |||
435 | (dev->mem_end & 0x3f) > 29) /* and less than 29K */ | |||
436 | dev->mem_end = RCV_RAM0x6000; /* or it will be set to 24K */ | |||
437 | else dev->mem_end = 1024*dev->mem_end; /* Maybe I should shift << 10 */ | |||
438 | ||||
439 | /* From now on, dev->mem_end contains the actual size of rx buffer */ | |||
440 | ||||
441 | if (net_debug > 3) | |||
442 | printk(", %dK RCV buffer", (int)(dev->mem_end)/1024); | |||
443 | ||||
444 | outb(BANK2_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x80),(ioaddr)) : __outb((0x80),(ioaddr))); /* be CAREFUL, BANK 2 now */ | |||
445 | id = inb(ioaddr + REG3)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __inbc(ioaddr + 0x03) : __inb(ioaddr + 0x03)); | |||
446 | if (id & TPE_BIT0x04) | |||
447 | dev->if_port = TPE; | |||
448 | else dev->if_port = BNC; | |||
449 | ||||
450 | if (net_debug>3) | |||
451 | printk("id: %x\n", id); | |||
452 | ||||
453 | if (dev->irq < 2 && eepro) { | |||
454 | i = read_eeprom(ioaddr, 1); | |||
455 | if (eepro == 1) | |||
456 | switch (i & 0x07) { | |||
457 | case 0: dev->irq = 9; break; | |||
458 | case 1: dev->irq = 3; break; | |||
459 | case 2: dev->irq = 5; break; | |||
460 | case 3: dev->irq = 10; break; | |||
461 | case 4: dev->irq = 11; break; | |||
462 | default: /* should never get here !!!!! */ | |||
463 | printk(" illegal interrupt vector stored in EEPROM.\n"); | |||
464 | return ENODEV19; | |||
465 | } | |||
466 | else switch (i & 0x07) { | |||
467 | case 0: dev->irq = 3; break; | |||
468 | case 1: dev->irq = 4; break; | |||
469 | case 2: dev->irq = 5; break; | |||
470 | case 3: dev->irq = 7; break; | |||
471 | case 4: dev->irq = 9; break; | |||
472 | case 5: dev->irq = 10; break; | |||
473 | case 6: dev->irq = 11; break; | |||
474 | case 7: dev->irq = 12; break; | |||
475 | } | |||
476 | } | |||
477 | else if (dev->irq == 2) | |||
478 | dev->irq = 9; | |||
479 | ||||
480 | if (dev->irq > 2) { | |||
481 | printk(", IRQ %d, %s.\n", dev->irq, | |||
482 | ifmap[dev->if_port]); | |||
483 | if (request_irq(dev->irq, &eepro_interrupt, 0, "eepro", NULL((void *) 0))) { | |||
484 | printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq); | |||
485 | return -EAGAIN11; | |||
486 | } | |||
487 | } | |||
488 | else printk(", %s.\n", ifmap[dev->if_port]); | |||
489 | ||||
490 | if ((dev->mem_start & 0xf) > 0) /* I don't know if this is */ | |||
491 | net_debug = dev->mem_start & 7; /* still useful or not */ | |||
492 | ||||
493 | if (net_debug > 3) { | |||
494 | i = read_eeprom(ioaddr, 5); | |||
495 | if (i & 0x2000) /* bit 13 of EEPROM word 5 */ | |||
496 | printk("%s: Concurrent Processing is enabled but not used!\n", | |||
497 | dev->name); | |||
498 | } | |||
499 | ||||
500 | if (net_debug) | |||
501 | printk(version); | |||
502 | ||||
503 | /* Grab the region so we can find another board if autoIRQ fails. */ | |||
504 | request_region(ioaddr, EEPRO_IO_EXTENT16, "eepro"); | |||
505 | ||||
506 | /* Initialize the device structure */ | |||
507 | dev->priv = kmalloclinux_kmalloc(sizeof(struct eepro_local), GFP_KERNEL0x03); | |||
508 | if (dev->priv == NULL((void *) 0)) | |||
509 | return -ENOMEM12; | |||
510 | memset(dev->priv, 0, sizeof(struct eepro_local))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(struct eepro_local))) ? __constant_c_and_count_memset(((dev->priv )),((0x01010101UL*(unsigned char)(0))),((sizeof(struct eepro_local )))) : __constant_c_memset(((dev->priv)),((0x01010101UL*(unsigned char)(0))),((sizeof(struct eepro_local))))) : (__builtin_constant_p ((sizeof(struct eepro_local))) ? __memset_generic((((dev-> priv))),(((0))),(((sizeof(struct eepro_local))))) : __memset_generic (((dev->priv)),((0)),((sizeof(struct eepro_local)))))); | |||
511 | ||||
512 | dev->open = eepro_open; | |||
513 | dev->stop = eepro_close; | |||
514 | dev->hard_start_xmit = eepro_send_packet; | |||
515 | dev->get_stats = eepro_get_stats; | |||
516 | dev->set_multicast_list = &set_multicast_list; | |||
517 | ||||
518 | /* Fill in the fields of the device structure with | |||
519 | ethernet generic values */ | |||
520 | ||||
521 | ether_setup(dev); | |||
522 | ||||
523 | outb(RESET_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x0e),(ioaddr)) : __outb((0x0e),(ioaddr))); /* RESET the 82595 */ | |||
524 | ||||
525 | return 0; | |||
526 | } | |||
527 | else return ENODEV19; | |||
528 | } | |||
529 | else if (net_debug > 3) | |||
530 | printk ("EtherExpress Pro probed failed!\n"); | |||
531 | return ENODEV19; | |||
532 | } | |||
533 | ||||
534 | /* Open/initialize the board. This is called (in the current kernel) | |||
535 | sometime after booting when the 'ifconfig' program is run. | |||
536 | ||||
537 | This routine should set everything up anew at each open, even | |||
538 | registers that "should" only need to be set once at boot, so that | |||
539 | there is non-reboot way to recover if something goes wrong. | |||
540 | */ | |||
541 | ||||
542 | static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1}; | |||
543 | static char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1}; | |||
544 | ||||
545 | static int | |||
546 | eepro_grab_irq(struct devicelinux_device *dev) | |||
547 | { | |||
548 | int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12 }; | |||
549 | int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr; | |||
550 | ||||
551 | outb(BANK1_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x40),(ioaddr)) : __outb((0x40),(ioaddr))); /* be CAREFUL, BANK 1 now */ | |||
552 | ||||
553 | /* Enable the interrupt line. */ | |||
554 | temp_reg = inb(ioaddr + REG1)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __inbc(ioaddr + 0x01) : __inb(ioaddr + 0x01)); | |||
555 | outb(temp_reg | INT_ENABLE, ioaddr + REG1)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((temp_reg | 0x80),(ioaddr + 0x01)) : __outb ((temp_reg | 0x80),(ioaddr + 0x01))); | |||
556 | ||||
557 | outb(BANK0_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x00),(ioaddr)) : __outb((0x00),(ioaddr))); /* be CAREFUL, BANK 0 now */ | |||
558 | ||||
559 | /* clear all interrupts */ | |||
560 | outb(ALL_MASK, ioaddr + STATUS_REG)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((0x0f),(ioaddr + 0x01)) : __outb((0x0f) ,(ioaddr + 0x01))); | |||
561 | ||||
562 | /* Let EXEC event to interrupt */ | |||
563 | outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((0x0f & ~(0x08)),(ioaddr + 0x03)) : __outb((0x0f & ~(0x08)),(ioaddr + 0x03))); | |||
564 | ||||
565 | do { | |||
566 | outb(BANK1_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x40),(ioaddr)) : __outb((0x40),(ioaddr))); /* be CAREFUL, BANK 1 now */ | |||
567 | temp_reg = inb(ioaddr + INT_NO_REG)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __inbc(ioaddr + 0x02) : __inb(ioaddr + 0x02)); | |||
568 | outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __outbc(((temp_reg & 0xf8) | irqrmap[*irqp] ),(ioaddr + 0x02)) : __outb(((temp_reg & 0xf8) | irqrmap[ *irqp]),(ioaddr + 0x02))); | |||
569 | outb(BANK0_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x00),(ioaddr)) : __outb((0x00),(ioaddr))); /* Switch back to Bank 0 */ | |||
570 | if (request_irq (*irqp, NULL((void *) 0), 0, "bogus", NULL((void *) 0)) != EBUSY16) { | |||
571 | /* Twinkle the interrupt, and check if it's seen */ | |||
572 | autoirq_setup(0); | |||
573 | outb(DIAGNOSE_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x07),(ioaddr)) : __outb((0x07),(ioaddr))); /* RESET the 82595 */ | |||
574 | ||||
575 | if (*irqp == autoirq_report(2) && /* It's a good IRQ line */ | |||
576 | (request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro", NULL((void *) 0)) == 0)) | |||
577 | break; | |||
578 | /* clear all interrupts */ | |||
579 | outb(ALL_MASK, ioaddr + STATUS_REG)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((0x0f),(ioaddr + 0x01)) : __outb((0x0f) ,(ioaddr + 0x01))); | |||
580 | } | |||
581 | } while (*++irqp); | |||
582 | ||||
583 | outb(BANK1_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x40),(ioaddr)) : __outb((0x40),(ioaddr))); /* Switch back to Bank 1 */ | |||
584 | ||||
585 | /* Disable the physical interrupt line. */ | |||
586 | temp_reg = inb(ioaddr + REG1)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __inbc(ioaddr + 0x01) : __inb(ioaddr + 0x01)); | |||
587 | outb(temp_reg & 0x7f, ioaddr + REG1)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((temp_reg & 0x7f),(ioaddr + 0x01)) : __outb((temp_reg & 0x7f),(ioaddr + 0x01))); | |||
588 | outb(BANK0_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x00),(ioaddr)) : __outb((0x00),(ioaddr))); /* Switch back to Bank 0 */ | |||
589 | ||||
590 | /* Mask all the interrupts. */ | |||
591 | outb(ALL_MASK, ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((0x0f),(ioaddr + 0x03)) : __outb((0x0f) ,(ioaddr + 0x03))); | |||
592 | ||||
593 | /* clear all interrupts */ | |||
594 | outb(ALL_MASK, ioaddr + STATUS_REG)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((0x0f),(ioaddr + 0x01)) : __outb((0x0f) ,(ioaddr + 0x01))); | |||
595 | ||||
596 | return dev->irq; | |||
597 | } | |||
598 | ||||
599 | static int | |||
600 | eepro_open(struct devicelinux_device *dev) | |||
601 | { | |||
602 | unsigned short temp_reg, old8, old9; | |||
603 | int i, ioaddr = dev->base_addr, rcv_ram = dev->mem_end; | |||
604 | struct eepro_local *lp = (struct eepro_local *)dev->priv; | |||
605 | ||||
606 | if (net_debug > 3) | |||
607 | printk("eepro: entering eepro_open routine.\n"); | |||
608 | ||||
609 | if ((dev->dev_addr[0] == SA_ADDR00x00 && | |||
610 | dev->dev_addr[1] == SA_ADDR10xaa && | |||
611 | dev->dev_addr[2] == SA_ADDR20x00)&& | |||
612 | (dev->dev_addr[3] != SA3_ADDR30xc9)) | |||
613 | { | |||
614 | lp->eepro = 1; | |||
615 | if (net_debug > 3) printk("p->eepro = 1;\n"); | |||
616 | } /* Yes, an Intel EtherExpress Pro/10 */ | |||
617 | ||||
618 | else if ((dev->dev_addr[0] == SA2_ADDR00x00 && | |||
619 | dev->dev_addr[1] == SA2_ADDR10xa0 && | |||
620 | dev->dev_addr[2] == SA2_ADDR20xc9)|| | |||
621 | (dev->dev_addr[0] == SA3_ADDR00x00 && | |||
622 | dev->dev_addr[1] == SA3_ADDR10xaa && | |||
623 | dev->dev_addr[2] == SA3_ADDR20x00 && | |||
624 | dev->dev_addr[3] == SA3_ADDR30xc9)) | |||
625 | { | |||
626 | lp->eepro = 2; /* Yes, an Intel EtherExpress Pro/10+ */ | |||
627 | if (net_debug > 3) printk("p->eepro = 2;\n"); | |||
628 | } | |||
629 | ||||
630 | else lp->eepro = 0; /* No, it is a generic 82585 lan card */ | |||
631 | ||||
632 | /* Get the interrupt vector for the 82595 */ | |||
633 | if (dev->irq < 2 && eepro_grab_irq(dev) == 0) { | |||
634 | printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq); | |||
635 | return -EAGAIN11; | |||
636 | } | |||
637 | ||||
638 | if (irq2dev_map[dev->irq] != 0 | |||
639 | || (irq2dev_map[dev->irq] = dev) == 0) | |||
640 | return -EAGAIN11; | |||
641 | ||||
642 | /* Initialize the 82595. */ | |||
643 | outb(BANK2_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x80),(ioaddr)) : __outb((0x80),(ioaddr))); /* be CAREFUL, BANK 2 now */ | |||
644 | temp_reg = inb(ioaddr + EEPROM_REG)((__builtin_constant_p((ioaddr + 0x0a)) && (ioaddr + 0x0a ) < 256) ? __inbc(ioaddr + 0x0a) : __inb(ioaddr + 0x0a)); | |||
645 | lp->stepping = temp_reg >> 5; /* Get the stepping number of the 595 */ | |||
646 | ||||
647 | if (net_debug > 3) | |||
648 | printk("The stepping of the 82595 is %d\n", lp->stepping); | |||
649 | if (temp_reg & 0x10) /* Check the TurnOff Enable bit */ | |||
650 | outb(temp_reg & 0xef, ioaddr + EEPROM_REG)((__builtin_constant_p((ioaddr + 0x0a)) && (ioaddr + 0x0a ) < 256) ? __outbc((temp_reg & 0xef),(ioaddr + 0x0a)) : __outb((temp_reg & 0xef),(ioaddr + 0x0a))); | |||
651 | for (i=0; i < 6; i++) | |||
652 | outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i)((__builtin_constant_p((ioaddr + 0x04 + i)) && (ioaddr + 0x04 + i) < 256) ? __outbc((dev->dev_addr[i]),(ioaddr + 0x04 + i)) : __outb((dev->dev_addr[i]),(ioaddr + 0x04 + i))); | |||
653 | ||||
654 | temp_reg = inb(ioaddr + REG1)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __inbc(ioaddr + 0x01) : __inb(ioaddr + 0x01)); /* Setup Transmit Chaining */ | |||
655 | outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop /* and discard bad RCV frames */((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((temp_reg | 0x20 | 0x40 | 0x80),(ioaddr + 0x01)) : __outb((temp_reg | 0x20 | 0x40 | 0x80),(ioaddr + 0x01 ))) | |||
656 | | RCV_Discard_BadFrame, ioaddr + REG1)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((temp_reg | 0x20 | 0x40 | 0x80),(ioaddr + 0x01)) : __outb((temp_reg | 0x20 | 0x40 | 0x80),(ioaddr + 0x01 ))); | |||
657 | temp_reg = inb(ioaddr + REG2)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __inbc(ioaddr + 0x02) : __inb(ioaddr + 0x02)); /* Match broadcast */ | |||
658 | outb(temp_reg | 0x14, ioaddr + REG2)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __outbc((temp_reg | 0x14),(ioaddr + 0x02)) : __outb ((temp_reg | 0x14),(ioaddr + 0x02))); | |||
659 | temp_reg = inb(ioaddr + REG3)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __inbc(ioaddr + 0x03) : __inb(ioaddr + 0x03)); | |||
660 | outb(temp_reg & 0x3f, ioaddr + REG3)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((temp_reg & 0x3f),(ioaddr + 0x03)) : __outb((temp_reg & 0x3f),(ioaddr + 0x03))); /* clear test mode */ | |||
661 | ||||
662 | /* Set the receiving mode */ | |||
663 | outb(BANK1_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x40),(ioaddr)) : __outb((0x40),(ioaddr))); /* be CAREFUL, BANK 1 now */ | |||
664 | ||||
665 | /* Set the interrupt vector */ | |||
666 | temp_reg = inb(ioaddr + INT_NO_REG)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __inbc(ioaddr + 0x02) : __inb(ioaddr + 0x02)); | |||
667 | ||||
668 | if (lp->eepro == 2) | |||
669 | outb((temp_reg & 0xf8) | irqrmap2[dev->irq], ioaddr + INT_NO_REG)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __outbc(((temp_reg & 0xf8) | irqrmap2[dev-> irq]),(ioaddr + 0x02)) : __outb(((temp_reg & 0xf8) | irqrmap2 [dev->irq]),(ioaddr + 0x02))); | |||
670 | else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __outbc(((temp_reg & 0xf8) | irqrmap[dev-> irq]),(ioaddr + 0x02)) : __outb(((temp_reg & 0xf8) | irqrmap [dev->irq]),(ioaddr + 0x02))); | |||
671 | ||||
672 | temp_reg = inb(ioaddr + INT_NO_REG)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __inbc(ioaddr + 0x02) : __inb(ioaddr + 0x02)); | |||
673 | ||||
674 | if (lp->eepro == 2) | |||
675 | outb((temp_reg & 0xf0) | irqrmap2[dev->irq] | 0x08,ioaddr+INT_NO_REG)((__builtin_constant_p((ioaddr+0x02)) && (ioaddr+0x02 ) < 256) ? __outbc(((temp_reg & 0xf0) | irqrmap2[dev-> irq] | 0x08),(ioaddr+0x02)) : __outb(((temp_reg & 0xf0) | irqrmap2[dev->irq] | 0x08),(ioaddr+0x02))); | |||
676 | else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __outbc(((temp_reg & 0xf8) | irqrmap[dev-> irq]),(ioaddr + 0x02)) : __outb(((temp_reg & 0xf8) | irqrmap [dev->irq]),(ioaddr + 0x02))); | |||
677 | ||||
678 | if (net_debug > 3) | |||
679 | printk("eepro_open: content of INT Reg is %x\n", temp_reg); | |||
680 | ||||
681 | ||||
682 | /* Initialize the RCV and XMT upper and lower limits */ | |||
683 | outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG)((__builtin_constant_p((ioaddr + 0x08)) && (ioaddr + 0x08 ) < 256) ? __outbc((0x00),(ioaddr + 0x08)) : __outb((0x00) ,(ioaddr + 0x08))); | |||
684 | outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG)((__builtin_constant_p((ioaddr + 0x09)) && (ioaddr + 0x09 ) < 256) ? __outbc(((((rcv_ram) - 2) >> 8)),(ioaddr + 0x09)) : __outb(((((rcv_ram) - 2) >> 8)),(ioaddr + 0x09 ))); | |||
685 | outb(XMT_LOWER_LIMIT, ioaddr + XMT_LOWER_LIMIT_REG)((__builtin_constant_p((ioaddr + 0x0a)) && (ioaddr + 0x0a ) < 256) ? __outbc((((rcv_ram) >> 8)),(ioaddr + 0x0a )) : __outb((((rcv_ram) >> 8)),(ioaddr + 0x0a))); | |||
686 | outb(XMT_UPPER_LIMIT, ioaddr + XMT_UPPER_LIMIT_REG)((__builtin_constant_p((ioaddr + 0x0b)) && (ioaddr + 0x0b ) < 256) ? __outbc((((0x8000 - 2) >> 8)),(ioaddr + 0x0b )) : __outb((((0x8000 - 2) >> 8)),(ioaddr + 0x0b))); | |||
687 | ||||
688 | /* Enable the interrupt line. */ | |||
689 | temp_reg = inb(ioaddr + REG1)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __inbc(ioaddr + 0x01) : __inb(ioaddr + 0x01)); | |||
690 | outb(temp_reg | INT_ENABLE, ioaddr + REG1)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((temp_reg | 0x80),(ioaddr + 0x01)) : __outb ((temp_reg | 0x80),(ioaddr + 0x01))); | |||
691 | outb(BANK0_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x00),(ioaddr)) : __outb((0x00),(ioaddr))); /* Switch back to Bank 0 */ | |||
692 | ||||
693 | /* Let RX and TX events to interrupt */ | |||
694 | outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((0x0f & ~(0x02 | 0x04)),(ioaddr + 0x03 )) : __outb((0x0f & ~(0x02 | 0x04)),(ioaddr + 0x03))); | |||
695 | ||||
696 | /* clear all interrupts */ | |||
697 | outb(ALL_MASK, ioaddr + STATUS_REG)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((0x0f),(ioaddr + 0x01)) : __outb((0x0f) ,(ioaddr + 0x01))); | |||
698 | ||||
699 | /* Initialize RCV */ | |||
700 | outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR)((__builtin_constant_p((ioaddr + 0x04)) && (ioaddr + 0x04 ) < 256) ? __outwc((0x00 << 8),(ioaddr + 0x04)) : __outw ((0x00 << 8),(ioaddr + 0x04))); | |||
701 | lp->rx_start = (RCV_LOWER_LIMIT0x00 << 8) ; | |||
702 | outw((RCV_UPPER_LIMIT << 8) | 0xfe, ioaddr + RCV_STOP)((__builtin_constant_p((ioaddr + 0x06)) && (ioaddr + 0x06 ) < 256) ? __outwc((((((rcv_ram) - 2) >> 8) << 8) | 0xfe),(ioaddr + 0x06)) : __outw((((((rcv_ram) - 2) >> 8) << 8) | 0xfe),(ioaddr + 0x06))); | |||
703 | ||||
704 | /* Initialize XMT */ | |||
705 | outw(XMT_LOWER_LIMIT << 8, ioaddr + XMT_BAR)((__builtin_constant_p((ioaddr + 0x0a)) && (ioaddr + 0x0a ) < 256) ? __outwc((((rcv_ram) >> 8) << 8),(ioaddr + 0x0a)) : __outw((((rcv_ram) >> 8) << 8),(ioaddr + 0x0a))); | |||
706 | ||||
707 | /* Check for the i82595TX and i82595FX */ | |||
708 | old8 = inb(ioaddr + 8)((__builtin_constant_p((ioaddr + 8)) && (ioaddr + 8) < 256) ? __inbc(ioaddr + 8) : __inb(ioaddr + 8)); | |||
709 | outb(~old8, ioaddr + 8)((__builtin_constant_p((ioaddr + 8)) && (ioaddr + 8) < 256) ? __outbc((~old8),(ioaddr + 8)) : __outb((~old8),(ioaddr + 8))); | |||
710 | ||||
711 | if ((temp_reg = inb(ioaddr + 8)((__builtin_constant_p((ioaddr + 8)) && (ioaddr + 8) < 256) ? __inbc(ioaddr + 8) : __inb(ioaddr + 8))) == old8) { | |||
712 | if (net_debug > 3) | |||
713 | printk("i82595 detected!\n"); | |||
714 | lp->version = LAN5950; | |||
715 | } | |||
716 | else { | |||
717 | lp->version = LAN595TX1; | |||
718 | outb(old8, ioaddr + 8)((__builtin_constant_p((ioaddr + 8)) && (ioaddr + 8) < 256) ? __outbc((old8),(ioaddr + 8)) : __outb((old8),(ioaddr + 8))); | |||
719 | old9 = inb(ioaddr + 9)((__builtin_constant_p((ioaddr + 9)) && (ioaddr + 9) < 256) ? __inbc(ioaddr + 9) : __inb(ioaddr + 9)); | |||
720 | outb(~old9, ioaddr + 9)((__builtin_constant_p((ioaddr + 9)) && (ioaddr + 9) < 256) ? __outbc((~old9),(ioaddr + 9)) : __outb((~old9),(ioaddr + 9))); | |||
721 | ||||
722 | if (((temp_reg = inb(ioaddr + 9)((__builtin_constant_p((ioaddr + 9)) && (ioaddr + 9) < 256) ? __inbc(ioaddr + 9) : __inb(ioaddr + 9))) == ( (~old9)&0xff) )) { | |||
723 | enum iftype { AUI=0, BNC=1, TPE=2 }; | |||
724 | ||||
725 | if (net_debug > 3) { | |||
726 | printk("temp_reg: %#x ~old9: %#x\n",temp_reg, ~old9); | |||
727 | printk("i82595FX detected!\n"); | |||
728 | } | |||
729 | ||||
730 | lp->version = LAN595FX2; | |||
731 | outb(old9, ioaddr + 9)((__builtin_constant_p((ioaddr + 9)) && (ioaddr + 9) < 256) ? __outbc((old9),(ioaddr + 9)) : __outb((old9),(ioaddr + 9))); | |||
732 | ||||
733 | if (dev->if_port != TPE) { /* Hopefully, this will fix the | |||
734 | problem of using Pentiums and | |||
735 | pro/10 w/ BNC. */ | |||
736 | outb(BANK2_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x80),(ioaddr)) : __outb((0x80),(ioaddr))); /* be CAREFUL, BANK 2 now */ | |||
737 | temp_reg = inb(ioaddr + REG13)((__builtin_constant_p((ioaddr + 0x0d)) && (ioaddr + 0x0d ) < 256) ? __inbc(ioaddr + 0x0d) : __inb(ioaddr + 0x0d)); | |||
738 | ||||
739 | /* disable the full duplex mode since it is not | |||
740 | applicable with the 10Base2 cable. */ | |||
741 | outb(temp_reg & ~(FDX | A_N_ENABLE), REG13)((__builtin_constant_p((0x0d)) && (0x0d) < 256) ? __outbc ((temp_reg & ~(0x00 | 0x02)),(0x0d)) : __outb((temp_reg & ~(0x00 | 0x02)),(0x0d))); | |||
742 | outb(BANK0_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x00),(ioaddr)) : __outb((0x00),(ioaddr))); /* be CAREFUL, BANK 0 now */ | |||
743 | } | |||
744 | } | |||
745 | else if (net_debug > 3) { | |||
746 | printk("temp_reg: %#x ~old9: %#x\n",temp_reg,((~old9)&0xff)); | |||
747 | printk("i82595TX detected!\n"); | |||
748 | } | |||
749 | } | |||
750 | ||||
751 | outb(SEL_RESET_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x1e),(ioaddr)) : __outb((0x1e),(ioaddr))); | |||
752 | ||||
753 | /* We are supposed to wait for 2 us after a SEL_RESET */ | |||
754 | SLOW_DOWN_IO__asm__ __volatile__("outb %al,$0x80"); | |||
755 | SLOW_DOWN_IO__asm__ __volatile__("outb %al,$0x80"); | |||
756 | ||||
757 | lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT((rcv_ram) >> 8) << 8; /* or = RCV_RAM */ | |||
758 | lp->tx_last = 0; | |||
759 | ||||
760 | dev->tbusy = 0; | |||
761 | dev->interrupt = 0; | |||
762 | dev->start = 1; | |||
763 | ||||
764 | if (net_debug > 3) | |||
765 | printk("eepro: exiting eepro_open routine.\n"); | |||
766 | ||||
767 | outb(RCV_ENABLE_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x08),(ioaddr)) : __outb((0x08),(ioaddr))); | |||
768 | MOD_INC_USE_COUNTdo { } while (0); | |||
769 | ||||
770 | return 0; | |||
771 | } | |||
772 | ||||
773 | static int | |||
774 | eepro_send_packet(struct sk_buff *skb, struct devicelinux_device *dev) | |||
775 | { | |||
776 | struct eepro_local *lp = (struct eepro_local *)dev->priv; | |||
777 | int ioaddr = dev->base_addr; | |||
778 | int rcv_ram = dev->mem_end; | |||
779 | ||||
780 | if (net_debug > 5) | |||
781 | printk("eepro: entering eepro_send_packet routine.\n"); | |||
782 | ||||
783 | if (dev->tbusy) { | |||
784 | /* If we get here, some higher level has decided we are broken. | |||
785 | There should really be a "kick me" function call instead. */ | |||
786 | ||||
787 | int tickssofar = jiffies - dev->trans_start; | |||
788 | ||||
789 | if (tickssofar < 40) | |||
790 | return 1; | |||
791 | ||||
792 | if (net_debug > 1) | |||
793 | printk("%s: transmit timed out, %s?\n", dev->name, | |||
794 | "network cable problem"); | |||
795 | ||||
796 | lp->stats.tx_errors++; | |||
797 | ||||
798 | /* Try to restart the adaptor. */ | |||
799 | outb(SEL_RESET_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x1e),(ioaddr)) : __outb((0x1e),(ioaddr))); | |||
800 | ||||
801 | /* We are supposed to wait for 2 us after a SEL_RESET */ | |||
802 | SLOW_DOWN_IO__asm__ __volatile__("outb %al,$0x80"); | |||
803 | SLOW_DOWN_IO__asm__ __volatile__("outb %al,$0x80"); | |||
804 | ||||
805 | /* Do I also need to flush the transmit buffers here? YES? */ | |||
806 | lp->tx_start = lp->tx_end = rcv_ram; | |||
807 | lp->tx_last = 0; | |||
808 | ||||
809 | dev->tbusy=0; | |||
810 | dev->trans_start = jiffies; | |||
811 | outb(RCV_ENABLE_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x08),(ioaddr)) : __outb((0x08),(ioaddr))); | |||
812 | } | |||
813 | ||||
814 | /* If some higher layer thinks we've missed an tx-done interrupt | |||
815 | we are passed NULL. Caution: dev_tint() handles the cli()/sti() | |||
816 | itself. */ | |||
817 | ||||
818 | if (skb == NULL((void *) 0)) { | |||
819 | dev_tint(dev); | |||
820 | return 0; | |||
821 | } | |||
822 | ||||
823 | /* Block a timer-based transmit from overlapping. */ | |||
824 | ||||
825 | if (set_bit(0, (void*)&dev->tbusy) != 0) | |||
826 | printk("%s: Transmitter access conflict.\n", dev->name); | |||
827 | else { | |||
828 | short length = ETH_ZLEN60 < skb->len ? skb->len : ETH_ZLEN60; | |||
829 | unsigned char *buf = skb->data; | |||
830 | hardware_send_packet(dev, buf, length); | |||
831 | dev->trans_start = jiffies; | |||
832 | } | |||
833 | ||||
834 | dev_kfree_skb (skb, FREE_WRITE0); | |||
835 | ||||
836 | /* You might need to clean up and record Tx statistics here. */ | |||
837 | /* lp->stats.tx_aborted_errors++; */ | |||
838 | ||||
839 | if (net_debug > 5) | |||
840 | printk("eepro: exiting eepro_send_packet routine.\n"); | |||
841 | ||||
842 | return 0; | |||
843 | } | |||
844 | ||||
845 | /* The typical workload of the driver: | |||
846 | Handle the network interface interrupts. */ | |||
847 | ||||
848 | static void | |||
849 | eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
850 | { | |||
851 | struct devicelinux_device *dev = (struct devicelinux_device *)(irq2dev_map[irq]); | |||
852 | int ioaddr, status, boguscount = 20; | |||
853 | ||||
854 | if (net_debug > 5) | |||
855 | printk("eepro: entering eepro_interrupt routine.\n"); | |||
856 | ||||
857 | if (dev == NULL((void *) 0)) { | |||
858 | printk ("eepro_interrupt(): irq %d for unknown device.\n", irq); | |||
859 | return; | |||
860 | } | |||
861 | ||||
862 | dev->interrupt = 1; | |||
863 | ||||
864 | ioaddr = dev->base_addr; | |||
865 | ||||
866 | do { | |||
867 | status = inb(ioaddr + STATUS_REG)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __inbc(ioaddr + 0x01) : __inb(ioaddr + 0x01)); | |||
868 | ||||
869 | if (status & RX_INT0x02) { | |||
870 | if (net_debug > 4) | |||
871 | printk("eepro: packet received interrupt.\n"); | |||
872 | /* Acknowledge the RX_INT */ | |||
873 | outb(RX_INT, ioaddr + STATUS_REG)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((0x02),(ioaddr + 0x01)) : __outb((0x02) ,(ioaddr + 0x01))); | |||
874 | /* Get the received packets */ | |||
875 | eepro_rx(dev); | |||
876 | } | |||
877 | else if (status & TX_INT0x04) { | |||
878 | if (net_debug > 4) | |||
879 | printk("eepro: packet transmit interrupt.\n"); | |||
880 | /* Acknowledge the TX_INT */ | |||
881 | outb(TX_INT, ioaddr + STATUS_REG)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((0x04),(ioaddr + 0x01)) : __outb((0x04) ,(ioaddr + 0x01))); | |||
882 | /* Process the status of transmitted packets */ | |||
883 | eepro_transmit_interrupt(dev); | |||
884 | } | |||
885 | ||||
886 | } while ((boguscount-- > 0) && (status & 0x06)); | |||
887 | ||||
888 | dev->interrupt = 0; | |||
889 | ||||
890 | if (net_debug > 5) | |||
891 | printk("eepro: exiting eepro_interrupt routine.\n"); | |||
892 | ||||
893 | return; | |||
894 | } | |||
895 | ||||
896 | static int | |||
897 | eepro_close(struct devicelinux_device *dev) | |||
898 | { | |||
899 | struct eepro_local *lp = (struct eepro_local *)dev->priv; | |||
900 | int ioaddr = dev->base_addr; | |||
901 | int rcv_ram = dev->mem_end; | |||
902 | short temp_reg; | |||
903 | ||||
904 | dev->tbusy = 1; | |||
905 | dev->start = 0; | |||
906 | ||||
907 | outb(BANK1_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x40),(ioaddr)) : __outb((0x40),(ioaddr))); /* Switch back to Bank 1 */ | |||
908 | ||||
909 | /* Disable the physical interrupt line. */ | |||
910 | temp_reg = inb(ioaddr + REG1)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __inbc(ioaddr + 0x01) : __inb(ioaddr + 0x01)); | |||
911 | outb(temp_reg & 0x7f, ioaddr + REG1)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((temp_reg & 0x7f),(ioaddr + 0x01)) : __outb((temp_reg & 0x7f),(ioaddr + 0x01))); | |||
912 | outb(BANK0_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x00),(ioaddr)) : __outb((0x00),(ioaddr))); /* Switch back to Bank 0 */ | |||
913 | ||||
914 | /* Flush the Tx and disable Rx. */ | |||
915 | outb(STOP_RCV_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x0b),(ioaddr)) : __outb((0x0b),(ioaddr))); | |||
916 | ||||
917 | lp->tx_start = lp->tx_end = rcv_ram ; | |||
918 | lp->tx_last = 0; | |||
919 | ||||
920 | /* Mask all the interrupts. */ | |||
921 | outb(ALL_MASK, ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((0x0f),(ioaddr + 0x03)) : __outb((0x0f) ,(ioaddr + 0x03))); | |||
922 | ||||
923 | /* clear all interrupts */ | |||
924 | outb(ALL_MASK, ioaddr + STATUS_REG)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((0x0f),(ioaddr + 0x01)) : __outb((0x0f) ,(ioaddr + 0x01))); | |||
925 | ||||
926 | /* Reset the 82595 */ | |||
927 | outb(RESET_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x0e),(ioaddr)) : __outb((0x0e),(ioaddr))); | |||
928 | ||||
929 | /* release the interrupt */ | |||
930 | free_irq(dev->irq, NULL((void *) 0)); | |||
931 | irq2dev_map[dev->irq] = 0; | |||
932 | ||||
933 | /* Update the statistics here. What statistics? */ | |||
934 | /* We are supposed to wait for 200 us after a RESET */ | |||
935 | SLOW_DOWN_IO__asm__ __volatile__("outb %al,$0x80"); | |||
936 | SLOW_DOWN_IO__asm__ __volatile__("outb %al,$0x80"); /* May not be enough? */ | |||
937 | MOD_DEC_USE_COUNTdo { } while (0); | |||
938 | ||||
939 | return 0; | |||
940 | } | |||
941 | ||||
942 | /* Get the current statistics. This may be called with the card open or | |||
943 | closed. */ | |||
944 | static struct enet_statistics * | |||
945 | eepro_get_stats(struct devicelinux_device *dev) | |||
946 | { | |||
947 | struct eepro_local *lp = (struct eepro_local *)dev->priv; | |||
948 | return &lp->stats; | |||
949 | } | |||
950 | ||||
951 | /* Set or clear the multicast filter for this adaptor. | |||
952 | */ | |||
953 | ||||
954 | static void | |||
955 | set_multicast_list(struct devicelinux_device *dev) | |||
956 | { | |||
957 | struct eepro_local *lp = (struct eepro_local *)dev->priv; | |||
958 | short ioaddr = dev->base_addr; | |||
959 | unsigned short mode; | |||
960 | struct dev_mc_list *dmi=dev->mc_list; | |||
961 | ||||
962 | if (dev->flags&(IFF_ALLMULTI0x200|IFF_PROMISC0x100) || dev->mc_count > 63) | |||
963 | { | |||
964 | /* | |||
965 | * We must make the kernel realise we had to move | |||
966 | * into promisc mode or we start all out war on | |||
967 | * the cable. If it was a promisc request the | |||
968 | * flag is already set. If not we assert it. | |||
969 | */ | |||
970 | dev->flags|=IFF_PROMISC0x100; | |||
971 | outb(BANK2_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x80),(ioaddr)) : __outb((0x80),(ioaddr))); /* be CAREFUL, BANK 2 now */ | |||
972 | mode = inb(ioaddr + REG2)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __inbc(ioaddr + 0x02) : __inb(ioaddr + 0x02)); | |||
973 | outb(mode | PRMSC_Mode, ioaddr + REG2)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __outbc((mode | 0x01),(ioaddr + 0x02)) : __outb ((mode | 0x01),(ioaddr + 0x02))); | |||
974 | mode = inb(ioaddr + REG3)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __inbc(ioaddr + 0x03) : __inb(ioaddr + 0x03)); | |||
975 | outb(mode, ioaddr + REG3)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((mode),(ioaddr + 0x03)) : __outb((mode) ,(ioaddr + 0x03))); /* writing reg. 3 to complete the update */ | |||
976 | outb(BANK0_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x00),(ioaddr)) : __outb((0x00),(ioaddr))); /* Return to BANK 0 now */ | |||
977 | printk("%s: promiscuous mode enabled.\n", dev->name); | |||
978 | } | |||
979 | ||||
980 | else if (dev->mc_count==0 ) | |||
981 | { | |||
982 | outb(BANK2_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x80),(ioaddr)) : __outb((0x80),(ioaddr))); /* be CAREFUL, BANK 2 now */ | |||
983 | mode = inb(ioaddr + REG2)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __inbc(ioaddr + 0x02) : __inb(ioaddr + 0x02)); | |||
984 | outb(mode & 0xd6, ioaddr + REG2)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __outbc((mode & 0xd6),(ioaddr + 0x02)) : __outb ((mode & 0xd6),(ioaddr + 0x02))); /* Turn off Multi-IA and PRMSC_Mode bits */ | |||
985 | mode = inb(ioaddr + REG3)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __inbc(ioaddr + 0x03) : __inb(ioaddr + 0x03)); | |||
986 | outb(mode, ioaddr + REG3)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((mode),(ioaddr + 0x03)) : __outb((mode) ,(ioaddr + 0x03))); /* writing reg. 3 to complete the update */ | |||
987 | outb(BANK0_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x00),(ioaddr)) : __outb((0x00),(ioaddr))); /* Return to BANK 0 now */ | |||
988 | } | |||
989 | ||||
990 | else | |||
991 | { | |||
992 | unsigned short status, *eaddrs; | |||
993 | int i, boguscount = 0; | |||
994 | ||||
995 | /* Disable RX and TX interrupts. Necessary to avoid | |||
996 | corruption of the HOST_ADDRESS_REG by interrupt | |||
997 | service routines. */ | |||
998 | outb(ALL_MASK, ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((0x0f),(ioaddr + 0x03)) : __outb((0x0f) ,(ioaddr + 0x03))); | |||
999 | outb(BANK2_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x80),(ioaddr)) : __outb((0x80),(ioaddr))); /* be CAREFUL, BANK 2 now */ | |||
1000 | mode = inb(ioaddr + REG2)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __inbc(ioaddr + 0x02) : __inb(ioaddr + 0x02)); | |||
1001 | outb(mode | Multi_IA, ioaddr + REG2)((__builtin_constant_p((ioaddr + 0x02)) && (ioaddr + 0x02 ) < 256) ? __outbc((mode | 0x20),(ioaddr + 0x02)) : __outb ((mode | 0x20),(ioaddr + 0x02))); | |||
1002 | mode = inb(ioaddr + REG3)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __inbc(ioaddr + 0x03) : __inb(ioaddr + 0x03)); | |||
1003 | outb(mode, ioaddr + REG3)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((mode),(ioaddr + 0x03)) : __outb((mode) ,(ioaddr + 0x03))); /* writing reg. 3 to complete the update */ | |||
1004 | outb(BANK0_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x00),(ioaddr)) : __outb((0x00),(ioaddr))); /* Return to BANK 0 now */ | |||
1005 | outw(lp->tx_end, ioaddr + HOST_ADDRESS_REG)((__builtin_constant_p((ioaddr + 0x0c)) && (ioaddr + 0x0c ) < 256) ? __outwc((lp->tx_end),(ioaddr + 0x0c)) : __outw ((lp->tx_end),(ioaddr + 0x0c))); | |||
1006 | outw(MC_SETUP, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((0x03),(ioaddr + 0x0e)) : __outw((0x03) ,(ioaddr + 0x0e))); | |||
1007 | outw(0, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((0),(ioaddr + 0x0e)) : __outw((0),(ioaddr + 0x0e))); | |||
1008 | outw(0, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((0),(ioaddr + 0x0e)) : __outw((0),(ioaddr + 0x0e))); | |||
1009 | outw(6*(dev->mc_count + 1), ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((6*(dev->mc_count + 1)),(ioaddr + 0x0e )) : __outw((6*(dev->mc_count + 1)),(ioaddr + 0x0e))); | |||
1010 | ||||
1011 | for (i = 0; i < dev->mc_count; i++) | |||
1012 | { | |||
1013 | eaddrs=(unsigned short *)dmi->dmi_addr; | |||
1014 | dmi=dmi->next; | |||
1015 | outw(*eaddrs++, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((*eaddrs++),(ioaddr + 0x0e)) : __outw(( *eaddrs++),(ioaddr + 0x0e))); | |||
1016 | outw(*eaddrs++, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((*eaddrs++),(ioaddr + 0x0e)) : __outw(( *eaddrs++),(ioaddr + 0x0e))); | |||
1017 | outw(*eaddrs++, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((*eaddrs++),(ioaddr + 0x0e)) : __outw(( *eaddrs++),(ioaddr + 0x0e))); | |||
1018 | } | |||
1019 | ||||
1020 | eaddrs = (unsigned short *) dev->dev_addr; | |||
1021 | outw(eaddrs[0], ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((eaddrs[0]),(ioaddr + 0x0e)) : __outw(( eaddrs[0]),(ioaddr + 0x0e))); | |||
1022 | outw(eaddrs[1], ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((eaddrs[1]),(ioaddr + 0x0e)) : __outw(( eaddrs[1]),(ioaddr + 0x0e))); | |||
1023 | outw(eaddrs[2], ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((eaddrs[2]),(ioaddr + 0x0e)) : __outw(( eaddrs[2]),(ioaddr + 0x0e))); | |||
1024 | outw(lp->tx_end, ioaddr + XMT_BAR)((__builtin_constant_p((ioaddr + 0x0a)) && (ioaddr + 0x0a ) < 256) ? __outwc((lp->tx_end),(ioaddr + 0x0a)) : __outw ((lp->tx_end),(ioaddr + 0x0a))); | |||
1025 | outb(MC_SETUP, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x03),(ioaddr)) : __outb((0x03),(ioaddr))); | |||
1026 | ||||
1027 | /* Update the transmit queue */ | |||
1028 | i = lp->tx_end + XMT_HEADER8 + 6*(dev->mc_count + 1); | |||
1029 | ||||
1030 | if (lp->tx_start != lp->tx_end) | |||
1031 | { | |||
1032 | /* update the next address and the chain bit in the | |||
1033 | last packet */ | |||
1034 | outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG)((__builtin_constant_p((ioaddr + 0x0c)) && (ioaddr + 0x0c ) < 256) ? __outwc((lp->tx_last + 0x04),(ioaddr + 0x0c) ) : __outw((lp->tx_last + 0x04),(ioaddr + 0x0c))); | |||
1035 | outw(i, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((i),(ioaddr + 0x0e)) : __outw((i),(ioaddr + 0x0e))); | |||
1036 | outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG)((__builtin_constant_p((ioaddr + 0x0c)) && (ioaddr + 0x0c ) < 256) ? __outwc((lp->tx_last + 0x06),(ioaddr + 0x0c) ) : __outw((lp->tx_last + 0x06),(ioaddr + 0x0c))); | |||
1037 | status = inw(ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __inwc(ioaddr + 0x0e) : __inw(ioaddr + 0x0e)); | |||
1038 | outw(status | CHAIN_BIT, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((status | 0x8000),(ioaddr + 0x0e)) : __outw ((status | 0x8000),(ioaddr + 0x0e))); | |||
1039 | lp->tx_end = i ; | |||
1040 | } | |||
1041 | else { | |||
1042 | lp->tx_start = lp->tx_end = i ; | |||
1043 | } | |||
1044 | ||||
1045 | /* Acknowledge that the MC setup is done */ | |||
1046 | do { /* We should be doing this in the eepro_interrupt()! */ | |||
1047 | SLOW_DOWN_IO__asm__ __volatile__("outb %al,$0x80"); | |||
1048 | SLOW_DOWN_IO__asm__ __volatile__("outb %al,$0x80"); | |||
1049 | ||||
1050 | if (inb(ioaddr + STATUS_REG)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __inbc(ioaddr + 0x01) : __inb(ioaddr + 0x01)) & 0x08) | |||
1051 | { | |||
1052 | i = inb(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __inbc(ioaddr) : __inb(ioaddr)); | |||
1053 | outb(0x08, ioaddr + STATUS_REG)((__builtin_constant_p((ioaddr + 0x01)) && (ioaddr + 0x01 ) < 256) ? __outbc((0x08),(ioaddr + 0x01)) : __outb((0x08) ,(ioaddr + 0x01))); | |||
1054 | ||||
1055 | if (i & 0x20) { /* command ABORTed */ | |||
1056 | printk("%s: multicast setup failed.\n", | |||
1057 | dev->name); | |||
1058 | break; | |||
1059 | } else if ((i & 0x0f) == 0x03) { /* MC-Done */ | |||
1060 | printk("%s: set Rx mode to %d addresses.\n", | |||
1061 | dev->name, dev->mc_count); | |||
1062 | break; | |||
1063 | } | |||
1064 | } | |||
1065 | } while (++boguscount < 100); | |||
1066 | ||||
1067 | /* Re-enable RX and TX interrupts */ | |||
1068 | outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((0x0f & ~(0x02 | 0x04)),(ioaddr + 0x03 )) : __outb((0x0f & ~(0x02 | 0x04)),(ioaddr + 0x03))); | |||
1069 | ||||
1070 | } | |||
1071 | outb(RCV_ENABLE_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x08),(ioaddr)) : __outb((0x08),(ioaddr))); | |||
1072 | } | |||
1073 | ||||
1074 | /* The horrible routine to read a word from the serial EEPROM. */ | |||
1075 | /* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */ | |||
1076 | /* The delay between EEPROM clock transitions. */ | |||
1077 | ||||
1078 | #define eeprom_delay(){ int _i = 40; while (--_i > 0) { __asm__ __volatile__("outb %al,$0x80" ); }} { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO__asm__ __volatile__("outb %al,$0x80"); }} | |||
1079 | #define EE_READ_CMD(6 << 6) (6 << 6) | |||
1080 | ||||
1081 | int | |||
1082 | read_eeprom(int ioaddr, int location) | |||
1083 | { | |||
1084 | int i; | |||
1085 | unsigned short retval = 0; | |||
1086 | short ee_addr = ioaddr + EEPROM_REG0x0a; | |||
1087 | int read_cmd = location | EE_READ_CMD(6 << 6); | |||
1088 | short ctrl_val = EECS0x02 ; | |||
1089 | ||||
1090 | outb(BANK2_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x80),(ioaddr)) : __outb((0x80),(ioaddr))); | |||
1091 | outb(ctrl_val, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256 ) ? __outbc((ctrl_val),(ee_addr)) : __outb((ctrl_val),(ee_addr ))); | |||
1092 | ||||
1093 | /* Shift the read command bits out. */ | |||
1094 | for (i = 8; i >= 0; i--) { | |||
1095 | short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI0x04 | |||
1096 | : ctrl_val; | |||
1097 | outb(outval, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256 ) ? __outbc((outval),(ee_addr)) : __outb((outval),(ee_addr))); | |||
1098 | outb(outval | EESK, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256 ) ? __outbc((outval | 0x01),(ee_addr)) : __outb((outval | 0x01 ),(ee_addr))); /* EEPROM clock tick. */ | |||
1099 | eeprom_delay(){ int _i = 40; while (--_i > 0) { __asm__ __volatile__("outb %al,$0x80" ); }}; | |||
1100 | outb(outval, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256 ) ? __outbc((outval),(ee_addr)) : __outb((outval),(ee_addr))); /* Finish EEPROM a clock tick. */ | |||
1101 | eeprom_delay(){ int _i = 40; while (--_i > 0) { __asm__ __volatile__("outb %al,$0x80" ); }}; | |||
1102 | } | |||
1103 | outb(ctrl_val, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256 ) ? __outbc((ctrl_val),(ee_addr)) : __outb((ctrl_val),(ee_addr ))); | |||
1104 | ||||
1105 | for (i = 16; i > 0; i--) { | |||
1106 | outb(ctrl_val | EESK, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256 ) ? __outbc((ctrl_val | 0x01),(ee_addr)) : __outb((ctrl_val | 0x01),(ee_addr))); eeprom_delay(){ int _i = 40; while (--_i > 0) { __asm__ __volatile__("outb %al,$0x80" ); }}; | |||
1107 | retval = (retval << 1) | ((inb(ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256 ) ? __inbc(ee_addr) : __inb(ee_addr)) & EEDO0x08) ? 1 : 0); | |||
1108 | outb(ctrl_val, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256 ) ? __outbc((ctrl_val),(ee_addr)) : __outb((ctrl_val),(ee_addr ))); eeprom_delay(){ int _i = 40; while (--_i > 0) { __asm__ __volatile__("outb %al,$0x80" ); }}; | |||
1109 | } | |||
1110 | /* Terminate the EEPROM access. */ | |||
1111 | ctrl_val &= ~EECS0x02; | |||
1112 | outb(ctrl_val | EESK, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256 ) ? __outbc((ctrl_val | 0x01),(ee_addr)) : __outb((ctrl_val | 0x01),(ee_addr))); | |||
1113 | eeprom_delay(){ int _i = 40; while (--_i > 0) { __asm__ __volatile__("outb %al,$0x80" ); }}; | |||
1114 | outb(ctrl_val, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256 ) ? __outbc((ctrl_val),(ee_addr)) : __outb((ctrl_val),(ee_addr ))); | |||
1115 | eeprom_delay(){ int _i = 40; while (--_i > 0) { __asm__ __volatile__("outb %al,$0x80" ); }}; | |||
1116 | outb(BANK0_SELECT, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x00),(ioaddr)) : __outb((0x00),(ioaddr))); | |||
1117 | return retval; | |||
1118 | } | |||
1119 | ||||
1120 | static void | |||
1121 | hardware_send_packet(struct devicelinux_device *dev, void *buf, short length) | |||
1122 | { | |||
1123 | struct eepro_local *lp = (struct eepro_local *)dev->priv; | |||
1124 | short ioaddr = dev->base_addr; | |||
1125 | int rcv_ram = dev->mem_end; | |||
1126 | unsigned status, tx_available, last, end, boguscount = 100; | |||
1127 | ||||
1128 | if (net_debug > 5) | |||
1129 | printk("eepro: entering hardware_send_packet routine.\n"); | |||
1130 | ||||
1131 | while (boguscount-- > 0) { | |||
1132 | ||||
1133 | /* Disable RX and TX interrupts. Necessary to avoid | |||
1134 | corruption of the HOST_ADDRESS_REG by interrupt | |||
1135 | service routines. */ | |||
1136 | outb(ALL_MASK, ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((0x0f),(ioaddr + 0x03)) : __outb((0x0f) ,(ioaddr + 0x03))); | |||
1137 | ||||
1138 | if (dev->interrupt == 1) { | |||
1139 | /* Enable RX and TX interrupts */ | |||
1140 | outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((0x0f & ~(0x02 | 0x04)),(ioaddr + 0x03 )) : __outb((0x0f & ~(0x02 | 0x04)),(ioaddr + 0x03))); | |||
1141 | continue; | |||
1142 | } | |||
1143 | ||||
1144 | /* determine how much of the transmit buffer space is available */ | |||
1145 | if (lp->tx_end > lp->tx_start) | |||
1146 | tx_available = XMT_RAM(0x8000 - (rcv_ram)) - (lp->tx_end - lp->tx_start); | |||
1147 | else if (lp->tx_end < lp->tx_start) | |||
1148 | tx_available = lp->tx_start - lp->tx_end; | |||
1149 | else tx_available = XMT_RAM(0x8000 - (rcv_ram)); | |||
1150 | ||||
1151 | if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER8) | |||
1152 | >= tx_available) /* No space available ??? */ | |||
1153 | { | |||
1154 | eepro_transmit_interrupt(dev); /* Clean up the transmiting queue */ | |||
1155 | /* Enable RX and TX interrupts */ | |||
1156 | outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((0x0f & ~(0x02 | 0x04)),(ioaddr + 0x03 )) : __outb((0x0f & ~(0x02 | 0x04)),(ioaddr + 0x03))); | |||
1157 | continue; | |||
1158 | } | |||
1159 | ||||
1160 | last = lp->tx_end; | |||
1161 | end = last + (((length + 3) >> 1) << 1) + XMT_HEADER8; | |||
1162 | if (end >= RAM_SIZE0x8000) { /* the transmit buffer is wrapped around */ | |||
1163 | ||||
1164 | if ((RAM_SIZE0x8000 - last) <= XMT_HEADER8) { | |||
1165 | /* Arrrr!!!, must keep the xmt header together, | |||
1166 | several days were lost to chase this one down. */ | |||
1167 | last = rcv_ram; | |||
1168 | end = last + (((length + 3) >> 1) << 1) + XMT_HEADER8; | |||
1169 | } | |||
1170 | ||||
1171 | else end = rcv_ram + (end - RAM_SIZE0x8000); | |||
1172 | } | |||
1173 | ||||
1174 | outw(last, ioaddr + HOST_ADDRESS_REG)((__builtin_constant_p((ioaddr + 0x0c)) && (ioaddr + 0x0c ) < 256) ? __outwc((last),(ioaddr + 0x0c)) : __outw((last) ,(ioaddr + 0x0c))); | |||
1175 | outw(XMT_CMD, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((0x04),(ioaddr + 0x0e)) : __outw((0x04) ,(ioaddr + 0x0e))); | |||
1176 | outw(0, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((0),(ioaddr + 0x0e)) : __outw((0),(ioaddr + 0x0e))); | |||
1177 | outw(end, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((end),(ioaddr + 0x0e)) : __outw((end),( ioaddr + 0x0e))); | |||
1178 | outw(length, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((length),(ioaddr + 0x0e)) : __outw((length ),(ioaddr + 0x0e))); | |||
1179 | ||||
1180 | if (lp->version == LAN5950) | |||
1181 | outsw(ioaddr + IO_PORT0x0e, buf, (length + 3) >> 1); | |||
1182 | ||||
1183 | else { /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */ | |||
1184 | unsigned short temp = inb(ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __inbc(ioaddr + 0x03) : __inb(ioaddr + 0x03)); | |||
1185 | outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((temp | 0x10),(ioaddr + 0x03)) : __outb ((temp | 0x10),(ioaddr + 0x03))); | |||
1186 | outsl(ioaddr + IO_PORT_32_BIT0x0c, buf, (length + 3) >> 2); | |||
1187 | outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((temp & ~(0x10)),(ioaddr + 0x03)) : __outb((temp & ~(0x10)),(ioaddr + 0x03))); | |||
1188 | } | |||
1189 | ||||
1190 | /* A dummy read to flush the DRAM write pipeline */ | |||
1191 | status = inw(ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __inwc(ioaddr + 0x0e) : __inw(ioaddr + 0x0e)); | |||
1192 | ||||
1193 | if (lp->tx_start == lp->tx_end) { | |||
1194 | outw(last, ioaddr + XMT_BAR)((__builtin_constant_p((ioaddr + 0x0a)) && (ioaddr + 0x0a ) < 256) ? __outwc((last),(ioaddr + 0x0a)) : __outw((last) ,(ioaddr + 0x0a))); | |||
1195 | outb(XMT_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x04),(ioaddr)) : __outb((0x04),(ioaddr))); | |||
1196 | lp->tx_start = last; /* I don't like to change tx_start here */ | |||
1197 | } | |||
1198 | else { | |||
1199 | /* update the next address and the chain bit in the | |||
1200 | last packet */ | |||
1201 | ||||
1202 | if (lp->tx_end != last) { | |||
1203 | outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG)((__builtin_constant_p((ioaddr + 0x0c)) && (ioaddr + 0x0c ) < 256) ? __outwc((lp->tx_last + 0x04),(ioaddr + 0x0c) ) : __outw((lp->tx_last + 0x04),(ioaddr + 0x0c))); | |||
1204 | outw(last, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((last),(ioaddr + 0x0e)) : __outw((last) ,(ioaddr + 0x0e))); | |||
1205 | } | |||
1206 | ||||
1207 | outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG)((__builtin_constant_p((ioaddr + 0x0c)) && (ioaddr + 0x0c ) < 256) ? __outwc((lp->tx_last + 0x06),(ioaddr + 0x0c) ) : __outw((lp->tx_last + 0x06),(ioaddr + 0x0c))); | |||
1208 | status = inw(ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __inwc(ioaddr + 0x0e) : __inw(ioaddr + 0x0e)); | |||
1209 | outw(status | CHAIN_BIT, ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __outwc((status | 0x8000),(ioaddr + 0x0e)) : __outw ((status | 0x8000),(ioaddr + 0x0e))); | |||
1210 | ||||
1211 | /* Continue the transmit command */ | |||
1212 | outb(RESUME_XMT_CMD, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256 ) ? __outbc((0x1c),(ioaddr)) : __outb((0x1c),(ioaddr))); | |||
1213 | } | |||
1214 | lp->tx_last = last; | |||
1215 | lp->tx_end = end; | |||
1216 | ||||
1217 | /* Enable RX and TX interrupts */ | |||
1218 | outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((0x0f & ~(0x02 | 0x04)),(ioaddr + 0x03 )) : __outb((0x0f & ~(0x02 | 0x04)),(ioaddr + 0x03))); | |||
1219 | ||||
1220 | if (dev->tbusy) { | |||
1221 | dev->tbusy = 0; | |||
1222 | } | |||
1223 | ||||
1224 | if (net_debug > 5) | |||
1225 | printk("eepro: exiting hardware_send_packet routine.\n"); | |||
1226 | ||||
1227 | return; | |||
1228 | } | |||
1229 | dev->tbusy = 1; | |||
1230 | ||||
1231 | if (net_debug > 5) | |||
1232 | printk("eepro: exiting hardware_send_packet routine.\n"); | |||
1233 | } | |||
1234 | ||||
1235 | static void | |||
1236 | eepro_rx(struct devicelinux_device *dev) | |||
1237 | { | |||
1238 | struct eepro_local *lp = (struct eepro_local *)dev->priv; | |||
1239 | short ioaddr = dev->base_addr, rcv_ram = dev->mem_end; | |||
1240 | short boguscount = 20; | |||
1241 | short rcv_car = lp->rx_start; | |||
1242 | unsigned rcv_event, rcv_status, rcv_next_frame, rcv_size; | |||
1243 | ||||
1244 | if (net_debug > 5) | |||
1245 | printk("eepro: entering eepro_rx routine.\n"); | |||
1246 | ||||
1247 | /* Set the read pointer to the start of the RCV */ | |||
1248 | outw(rcv_car, ioaddr + HOST_ADDRESS_REG)((__builtin_constant_p((ioaddr + 0x0c)) && (ioaddr + 0x0c ) < 256) ? __outwc((rcv_car),(ioaddr + 0x0c)) : __outw((rcv_car ),(ioaddr + 0x0c))); | |||
1249 | ||||
1250 | rcv_event = inw(ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __inwc(ioaddr + 0x0e) : __inw(ioaddr + 0x0e)); | |||
1251 | while (rcv_event == RCV_DONE0x0008) { | |||
1252 | ||||
1253 | rcv_status = inw(ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __inwc(ioaddr + 0x0e) : __inw(ioaddr + 0x0e)); | |||
1254 | rcv_next_frame = inw(ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __inwc(ioaddr + 0x0e) : __inw(ioaddr + 0x0e)); | |||
1255 | rcv_size = inw(ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __inwc(ioaddr + 0x0e) : __inw(ioaddr + 0x0e)); | |||
1256 | ||||
1257 | if ((rcv_status & (RX_OK0x2000 | RX_ERROR0x0d81)) == RX_OK0x2000) { | |||
1258 | ||||
1259 | /* Malloc up new buffer. */ | |||
1260 | struct sk_buff *skb; | |||
1261 | rcv_size &= 0x3fff; | |||
1262 | skb = dev_alloc_skb(rcv_size+5); | |||
1263 | ||||
1264 | if (skb == NULL((void *) 0)) { | |||
1265 | printk("%s: Memory squeeze, dropping packet.\n", dev->name); | |||
1266 | lp->stats.rx_dropped++; | |||
1267 | break; | |||
1268 | } | |||
1269 | ||||
1270 | skb->dev = dev; | |||
1271 | skb_reserve(skb,2); | |||
1272 | ||||
1273 | if (lp->version == LAN5950) | |||
1274 | insw(ioaddr+IO_PORT0x0e, skb_put(skb,rcv_size), (rcv_size + 3) >> 1); | |||
1275 | ||||
1276 | else { /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */ | |||
1277 | unsigned short temp = inb(ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __inbc(ioaddr + 0x03) : __inb(ioaddr + 0x03)); | |||
1278 | outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((temp | 0x10),(ioaddr + 0x03)) : __outb ((temp | 0x10),(ioaddr + 0x03))); | |||
1279 | insl(ioaddr+IO_PORT_32_BIT0x0c, skb_put(skb,rcv_size), (rcv_size + 3) >> 2); | |||
1280 | outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG)((__builtin_constant_p((ioaddr + 0x03)) && (ioaddr + 0x03 ) < 256) ? __outbc((temp & ~(0x10)),(ioaddr + 0x03)) : __outb((temp & ~(0x10)),(ioaddr + 0x03))); | |||
1281 | } | |||
1282 | ||||
1283 | skb->protocol = eth_type_trans(skb,dev)((unsigned short)0); | |||
1284 | netif_rx(skb); | |||
1285 | lp->stats.rx_packets++; | |||
1286 | } | |||
1287 | ||||
1288 | else { /* Not sure will ever reach here, | |||
1289 | I set the 595 to discard bad received frames */ | |||
1290 | lp->stats.rx_errors++; | |||
1291 | ||||
1292 | if (rcv_status & 0x0100) | |||
1293 | lp->stats.rx_over_errors++; | |||
1294 | ||||
1295 | else if (rcv_status & 0x0400) | |||
1296 | lp->stats.rx_frame_errors++; | |||
1297 | ||||
1298 | else if (rcv_status & 0x0800) | |||
1299 | lp->stats.rx_crc_errors++; | |||
1300 | ||||
1301 | printk("%s: event = %#x, status = %#x, next = %#x, size = %#x\n", | |||
1302 | dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size); | |||
1303 | } | |||
1304 | ||||
1305 | if (rcv_status & 0x1000) | |||
1306 | lp->stats.rx_length_errors++; | |||
1307 | ||||
1308 | if (--boguscount == 0) | |||
1309 | break; | |||
1310 | ||||
1311 | rcv_car = lp->rx_start + RCV_HEADER8 + rcv_size; | |||
1312 | lp->rx_start = rcv_next_frame; | |||
1313 | outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG)((__builtin_constant_p((ioaddr + 0x0c)) && (ioaddr + 0x0c ) < 256) ? __outwc((rcv_next_frame),(ioaddr + 0x0c)) : __outw ((rcv_next_frame),(ioaddr + 0x0c))); | |||
1314 | rcv_event = inw(ioaddr + IO_PORT)((__builtin_constant_p((ioaddr + 0x0e)) && (ioaddr + 0x0e ) < 256) ? __inwc(ioaddr + 0x0e) : __inw(ioaddr + 0x0e)); | |||
1315 | } | |||
1316 | if (rcv_car == 0) | |||
1317 | rcv_car = (RCV_UPPER_LIMIT(((rcv_ram) - 2) >> 8) << 8) | 0xff; | |||
1318 | ||||
1319 | outw(rcv_car - 1, ioaddr + RCV_STOP)((__builtin_constant_p((ioaddr + 0x06)) && (ioaddr + 0x06 ) < 256) ? __outwc((rcv_car - 1),(ioaddr + 0x06)) : __outw ((rcv_car - 1),(ioaddr + 0x06))); | |||
1320 | ||||
1321 | if (net_debug > 5) | |||
1322 | printk("eepro: exiting eepro_rx routine.\n"); | |||
1323 | } | |||
1324 | ||||
1325 | static void | |||
1326 | eepro_transmit_interrupt(struct devicelinux_device *dev) | |||
1327 | { | |||
1328 | struct eepro_local *lp = (struct eepro_local *)dev->priv; | |||
1329 | short ioaddr = dev->base_addr; | |||
1330 | short boguscount = 20; | |||
1331 | short xmt_status; | |||
1332 | ||||
1333 | while (lp->tx_start != lp->tx_end) { | |||
1334 | ||||
1335 | outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG)((__builtin_constant_p((ioaddr + 0x0c)) && (ioaddr + 0x0c ) < 256) ? __outwc((lp->tx_start),(ioaddr + 0x0c)) : __outw ((lp->tx_start),(ioaddr + 0x0c))); | |||
1336 | xmt_status = inw(ioaddr+IO_PORT)((__builtin_constant_p((ioaddr+0x0e)) && (ioaddr+0x0e ) < 256) ? __inwc(ioaddr+0x0e) : __inw(ioaddr+0x0e)); | |||
1337 | ||||
1338 | if ((xmt_status & TX_DONE_BIT0x0080) == 0) break; | |||
1339 | ||||
1340 | xmt_status = inw(ioaddr+IO_PORT)((__builtin_constant_p((ioaddr+0x0e)) && (ioaddr+0x0e ) < 256) ? __inwc(ioaddr+0x0e) : __inw(ioaddr+0x0e)); | |||
1341 | lp->tx_start = inw(ioaddr+IO_PORT)((__builtin_constant_p((ioaddr+0x0e)) && (ioaddr+0x0e ) < 256) ? __inwc(ioaddr+0x0e) : __inw(ioaddr+0x0e)); | |||
1342 | dev->tbusy = 0; | |||
1343 | mark_bh(NET_BH); | |||
1344 | ||||
1345 | if (xmt_status & 0x2000) | |||
1346 | lp->stats.tx_packets++; | |||
1347 | else { | |||
1348 | lp->stats.tx_errors++; | |||
1349 | if (xmt_status & 0x0400) | |||
1350 | lp->stats.tx_carrier_errors++; | |||
1351 | printk("%s: XMT status = %#x\n", | |||
1352 | dev->name, xmt_status); | |||
1353 | } | |||
1354 | ||||
1355 | if (xmt_status & 0x000f) { | |||
1356 | lp->stats.collisions += (xmt_status & 0x000f); | |||
1357 | } | |||
1358 | ||||
1359 | if ((xmt_status & 0x0040) == 0x0) { | |||
1360 | lp->stats.tx_heartbeat_errors++; | |||
1361 | } | |||
1362 | ||||
1363 | if (--boguscount == 0) | |||
1364 | break; | |||
1365 | } | |||
1366 | } | |||
1367 | ||||
1368 | #ifdef MODULE | |||
1369 | ||||
1370 | static char devicename[9] = { 0, }; | |||
1371 | static struct devicelinux_device dev_eepro = { | |||
1372 | devicename, /* device name is inserted by linux/drivers/net/net_init.c */ | |||
1373 | 0, 0, 0, 0, | |||
1374 | 0, 0, | |||
1375 | 0, 0, 0, NULL((void *) 0), eepro_probe }; | |||
1376 | static int io = 0x200; | |||
1377 | static int irq = 0; | |||
1378 | static int mem = (RCV_RAM0x6000/1024); /* Size of the rx buffer in KB */ | |||
1379 | ||||
1380 | int | |||
1381 | init_module(void) | |||
1382 | { | |||
1383 | if (io == 0) | |||
1384 | printk("eepro: You should not use auto-probing with insmod!\n"); | |||
1385 | ||||
1386 | dev_eepro.base_addr = io; | |||
1387 | dev_eepro.irq = irq; | |||
1388 | dev_eepro.mem_end = mem; | |||
1389 | ||||
1390 | if (register_netdev(&dev_eepro) != 0) | |||
1391 | return -EIO5; | |||
1392 | ||||
1393 | return 0; | |||
1394 | } | |||
1395 | ||||
1396 | void | |||
1397 | cleanup_module(void) | |||
1398 | { | |||
1399 | unregister_netdev(&dev_eepro); | |||
1400 | ||||
1401 | kfree_s(dev_eepro.priv,sizeof(struct eepro_local))linux_kfree(dev_eepro.priv); | |||
1402 | dev_eepro.priv=NULL((void *) 0); | |||
1403 | ||||
1404 | /* If we don't do this, we can't re-insmod it later. */ | |||
1405 | release_region(dev_eepro.base_addr, EEPRO_IO_EXTENT16); | |||
1406 | } | |||
1407 | #endif /* MODULE */ |