| 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 */ |