| File: | obj-scan-build/../linux/src/drivers/net/eepro.c |
| Location: | line 1191, column 3 |
| Description: | Value stored to 'status' is never read |
| 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)); |
Value stored to 'status' is never read | |
| 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 */ |