2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Novell Eagle 2000 driver
5 * PURPOSE: DP8390 NIC specific routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 27/08-2000 Created
13 /* Null-terminated array of ports to probe. This is "semi-risky" (Don Becker). */
14 ULONG_PTR ProbeAddressList
[] = { 0x280, 0x300, 0x320, 0x340, 0x360, 0x380, 0 };
16 static BOOLEAN
ProbeAddressForNIC(
19 * FUNCTION: Probes an address for a NIC
21 * address = Base address to probe
23 * TRUE if an NIC is found at the address
26 * If the adapter responds correctly to a
27 * stop command we assume it is present
32 NDIS_DbgPrint(MID_TRACE
, ("Probing address 0x%x\n", address
));
34 /* Disable interrupts */
35 NdisRawWritePortUchar(address
+ PG0_IMR
, 0);
38 NdisRawWritePortUchar(address
+ PG0_CR
, CR_STP
| CR_RD2
);
41 NdisStallExecution(1600);
43 /* Read NIC response */
44 NdisRawReadPortUchar(address
+ PG0_CR
, &Tmp
);
46 if ((Tmp
== (CR_RD2
| CR_STP
)) || (Tmp
== (CR_RD2
| CR_STP
| CR_STA
)))
56 * FUNCTION: Tests for a NIC
58 * Adapter = Pointer to adapter information
60 * TRUE if NIC is believed to be present, FALSE if not
65 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
67 /* first try the supplied value */
68 if(ProbeAddressForNIC(Adapter
->IoBaseAddress
))
70 NDIS_DbgPrint(MID_TRACE
, ("Found adapter at 0x%x\n", Adapter
->IoBaseAddress
));
74 /* ok, no dice, time to probe */
75 for(i
= 0; ProbeAddressList
[i
]; i
++)
77 if(ProbeAddressForNIC(ProbeAddressList
[i
]))
79 NDIS_DbgPrint(MID_TRACE
, ("Found adapter at address 0x%x\n", ProbeAddressList
[i
]));
80 Adapter
->IoBaseAddress
= ProbeAddressList
[i
];
85 NDIS_DbgPrint(MIN_TRACE
,("Adapter NOT found!\n"));
90 static BOOLEAN
NICTestAddress(
94 * FUNCTION: Tests if an address is writable
96 * Adapter = Pointer to adapter information
98 * TRUE if the address is writable, FALSE if not
105 NICReadDataAlign(Adapter
, &Data
, Address
, 0x02);
111 NICWriteDataAlign(Adapter
, Address
, &Data
, 0x02);
113 /* Check if it has changed on the NIC */
114 NICReadDataAlign(Adapter
, &Tmp
, Address
, 0x02);
116 return (Data
== Tmp
);
120 static BOOLEAN
NICTestRAM(
121 PNIC_ADAPTER Adapter
)
123 * FUNCTION: Finds out how much RAM a NIC has
125 * Adapter = Pointer to adapter information
127 * TRUE if the RAM size was found, FALSE if not
129 * Start at 1KB and test for every 1KB up to 64KB
134 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
136 /* Locate RAM base address */
137 for (Base
= 0x0400; Base
< 0x10000; Base
+= 0x0400) {
138 if (NICTestAddress(Adapter
, Base
))
142 if (Base
== 0x10000) {
143 /* No RAM on this board */
144 NDIS_DbgPrint(MIN_TRACE
, ("No RAM found on board.\n"));
148 Adapter
->RamBase
= (PUCHAR
)Base
;
151 for (; Base
< 0x10000; Base
+= 0x0400) {
152 if (!NICTestAddress(Adapter
, Base
))
156 Adapter
->RamSize
= (UINT
)(Base
- (ULONG_PTR
)Adapter
->RamBase
);
158 NDIS_DbgPrint(MID_TRACE
, ("RAM is at (0x%X). Size is (0x%X).\n",
159 Adapter
->RamBase
, Adapter
->RamSize
));
165 static VOID
NICSetPhysicalAddress(
166 PNIC_ADAPTER Adapter
)
168 * FUNCTION: Initializes the physical address on the NIC
170 * Adapter = Pointer to adapter information
172 * The physical address is taken from Adapter.
173 * The NIC is stopped by this operation
179 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STP
| CR_RD2
| CR_PAGE1
);
181 /* Initialize PAR - Physical Address Registers */
182 for (i
= 0; i
< 0x06; i
++)
183 NdisRawWritePortUchar(Adapter
->IOBase
+ PG1_PAR
+ i
, Adapter
->StationAddress
[i
]);
185 /* Go back to page 0 */
186 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STP
| CR_RD2
| CR_PAGE0
);
190 static VOID
NICSetMulticastAddressMask(
191 PNIC_ADAPTER Adapter
)
193 * FUNCTION: Initializes the multicast address mask on the NIC
195 * Adapter = Pointer to adapter information
197 * The multicast address mask is taken from Adapter.
198 * The NIC is stopped by this operation
204 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STP
| CR_RD2
| CR_PAGE1
);
206 /* Initialize MAR - Multicast Address Registers */
207 for (i
= 0; i
< 0x08; i
++)
208 NdisRawWritePortUchar(Adapter
->IOBase
+ PG1_MAR
+ i
, Adapter
->MulticastAddressMask
[i
]);
210 /* Go back to page 0 */
211 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STP
| CR_RD2
| CR_PAGE0
);
215 static BOOLEAN
NICReadSAPROM(
216 PNIC_ADAPTER Adapter
)
218 * FUNCTION: Reads the Station Address PROM data from the NIC
220 * Adapter = Pointer to adapter information
222 * TRUE if a the NIC is an NE2000
224 * This routine also determines if the NIC can support word mode transfers
225 * and if it does initializes the NIC for word mode.
226 * The station address in the adapter structure is initialized with
227 * the address from the SAPROM
234 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
236 /* Read Station Address PROM (SAPROM) which is 16 bytes at remote DMA address 0.
237 Some cards double the data read which we must compensate for */
239 /* Initialize RBCR0 and RBCR1 - Remote Byte Count Registers */
240 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR0
, 0x20);
241 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR1
, 0x00);
243 /* Initialize RSAR0 and RSAR1 - Remote Start Address Registers */
244 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RSAR0
, 0x00);
245 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RSAR1
, 0x00);
247 /* Select page 0, read and start the NIC */
248 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD0
| CR_PAGE0
);
250 /* Read one byte at a time */
251 WordLength
= 2; /* Assume a word is two bytes */
252 for (i
= 0; i
< 32; i
+= 2) {
253 NdisRawReadPortUchar(Adapter
->IOBase
+ NIC_DATA
, &Buffer
[i
]);
254 NdisRawReadPortUchar(Adapter
->IOBase
+ NIC_DATA
, &Buffer
[i
+ 1]);
255 if (Buffer
[i
] != Buffer
[i
+ 1])
256 WordLength
= 1; /* A word is one byte long */
259 /* If WordLength is 2 the data read before was doubled. We must compensate for this */
260 if (WordLength
== 2) {
261 NDIS_DbgPrint(MAX_TRACE
,("NE2000 or compatible network adapter found.\n"));
263 Adapter
->WordMode
= TRUE
;
265 /* Move the SAPROM data to the adapter object */
266 for (i
= 0; i
< 16; i
++)
267 Adapter
->SAPROM
[i
] = Buffer
[i
* 2];
269 /* Copy the station address */
271 (PVOID
)&Adapter
->StationAddress
,
272 (PVOID
)&Adapter
->SAPROM
,
273 DRIVER_LENGTH_OF_ADDRESS
);
275 /* Initialize DCR - Data Configuration Register (word mode/4 words FIFO) */
276 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_DCR
, DCR_WTS
| DCR_LS
| DCR_FT10
);
280 NDIS_DbgPrint(MAX_TRACE
, ("NE1000 or compatible network adapter found.\n"));
282 Adapter
->WordMode
= FALSE
;
289 NDIS_STATUS
NICInitialize(
290 PNIC_ADAPTER Adapter
)
292 * FUNCTION: Initializes a NIC
294 * Adapter = Pointer to adapter information
296 * Status of NIC initialization
298 * The NIC is put into loopback mode
303 NDIS_DbgPrint(MID_TRACE
, ("Called.\n"));
306 NdisRawReadPortUchar(Adapter
->IOBase
+ NIC_RESET
, &Tmp
);
309 NdisStallExecution(1600);
311 /* Write the value back */
312 NdisRawWritePortUchar(Adapter
->IOBase
+ NIC_RESET
, Tmp
);
314 /* Select page 0 and stop NIC */
315 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STP
| CR_RD2
| CR_PAGE0
);
317 /* Initialize DCR - Data Configuration Register (byte mode/8 bytes FIFO) */
318 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_DCR
, DCR_LS
| DCR_FT10
);
320 /* Clear RBCR0 and RBCR1 - Remote Byte Count Registers */
321 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR0
, 0x00);
322 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR1
, 0x00);
324 /* Initialize RCR - Receive Configuration Register (monitor mode) */
325 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RCR
, RCR_MON
);
327 /* Enter loopback mode (internal NIC module loopback) */
328 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_TCR
, TCR_LOOP
);
330 /* Read the Station Address PROM */
331 if (!NICReadSAPROM(Adapter
))
332 return NDIS_STATUS_ADAPTER_NOT_FOUND
;
334 NDIS_DbgPrint(MID_TRACE
, ("Station address is (%02X %02X %02X %02X %02X %02X).\n",
335 Adapter
->StationAddress
[0], Adapter
->StationAddress
[1],
336 Adapter
->StationAddress
[2], Adapter
->StationAddress
[3],
337 Adapter
->StationAddress
[4], Adapter
->StationAddress
[5]));
339 /* Select page 0 and start NIC */
340 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD2
| CR_PAGE0
);
342 /* Clear ISR - Interrupt Status Register */
343 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_ISR
, 0xFF);
345 /* Find NIC RAM size */
348 return NDIS_STATUS_SUCCESS
;
352 NDIS_STATUS
NICSetup(
353 PNIC_ADAPTER Adapter
)
355 * FUNCTION: Sets up a NIC
357 * Adapter = Pointer to adapter information
359 * Status of operation
361 * The NIC is put into loopback mode
364 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
366 if (Adapter
->WordMode
) {
367 /* Initialize DCR - Data Configuration Register (word mode/4 words FIFO) */
368 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_DCR
, DCR_WTS
| DCR_LS
| DCR_FT10
);
370 /* Initialize DCR - Data Configuration Register (byte mode/8 bytes FIFO) */
371 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_DCR
, DCR_LS
| DCR_FT10
);
374 /* Clear RBCR0 and RBCR1 - Remote Byte Count Registers */
375 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR0
, 0x00);
376 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR1
, 0x00);
378 /* Initialize RCR - Receive Configuration Register (monitor mode) */
379 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RCR
, RCR_MON
);
381 /* Enter loopback mode (internal NIC module loopback) */
382 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_TCR
, TCR_LOOP
);
384 /* Set boundary page */
385 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_BNRY
, Adapter
->NextPacket
);
388 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_PSTART
, Adapter
->PageStart
);
391 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_PSTOP
, Adapter
->PageStop
);
393 /* Program our address on the NIC */
394 NICSetPhysicalAddress(Adapter
);
396 /* Program the multicast address mask on the NIC */
397 NICSetMulticastAddressMask(Adapter
);
399 /* Select page 1 and stop NIC */
400 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STP
| CR_RD2
| CR_PAGE1
);
402 /* Initialize current page register */
403 NdisRawWritePortUchar(Adapter
->IOBase
+ PG1_CURR
, Adapter
->PageStart
+ 1);
405 /* Select page 0 and stop NIC */
406 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STP
| CR_RD2
| CR_PAGE0
);
408 /* Clear ISR - Interrupt Status Register */
409 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_ISR
, 0xFF);
411 /* Initialize IMR - Interrupt Mask Register */
412 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_IMR
, Adapter
->InterruptMask
);
414 /* Select page 0 and start NIC */
415 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD2
| CR_PAGE0
);
417 Adapter
->CurrentPage
= Adapter
->PageStart
+ 1;
418 Adapter
->NextPacket
= Adapter
->PageStart
+ 1;
419 Adapter
->BufferOverflow
= FALSE
;
420 Adapter
->ReceiveError
= FALSE
;
421 Adapter
->TransmitError
= FALSE
;
423 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
425 return NDIS_STATUS_SUCCESS
;
429 NDIS_STATUS
NICStart(
430 PNIC_ADAPTER Adapter
)
432 * FUNCTION: Starts a NIC
434 * Adapter = Pointer to adapter information
436 * Status of operation
439 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
441 /* Take NIC out of loopback mode */
442 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_TCR
, 0x00);
444 /* Initialize RCR - Receive Configuration Register (accept all) */
445 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RCR
, RCR_AB
| RCR_AM
| RCR_PRO
);
447 return NDIS_STATUS_SUCCESS
;
452 PNIC_ADAPTER Adapter
)
454 * FUNCTION: Stops a NIC
456 * Adapter = Pointer to adapter information
458 * Status of operation
464 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
466 /* Select page 0 and stop NIC */
467 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STP
| CR_RD2
| CR_PAGE0
);
469 /* Clear Remote Byte Count Register so ISR_RST will be set */
470 NdisRawWritePortUchar( Adapter
->IOBase
+ PG0_RBCR0
, 0x00);
471 NdisRawWritePortUchar( Adapter
->IOBase
+ PG0_RBCR0
, 0x00);
473 /* Wait for ISR_RST to be set, but timeout after 2ms */
474 for (i
= 0; i
< 4; i
++) {
475 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_ISR
, &Tmp
);
479 NdisStallExecution(500);
484 NDIS_DbgPrint(MIN_TRACE
, ("NIC was not reset after 2ms.\n"));
487 /* Initialize RCR - Receive Configuration Register (monitor mode) */
488 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RCR
, RCR_MON
);
490 /* Initialize TCR - Transmit Configuration Register (loopback mode) */
491 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_TCR
, TCR_LOOP
);
494 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD2
);
496 return NDIS_STATUS_SUCCESS
;
500 NDIS_STATUS
NICReset(
501 PNIC_ADAPTER Adapter
)
503 * FUNCTION: Resets a NIC
505 * Adapter = Pointer to adapter information
507 * Status of operation
512 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
518 NdisRawReadPortUchar(Adapter
->IOBase
+ NIC_RESET
, &Tmp
);
521 NdisStallExecution(1600);
523 /* Write the value back */
524 NdisRawWritePortUchar(Adapter
->IOBase
+ NIC_RESET
, Tmp
);
526 /* Restart the NIC */
529 return NDIS_STATUS_SUCCESS
;
533 static VOID
NICStartTransmit(
534 PNIC_ADAPTER Adapter
)
536 * FUNCTION: Starts transmitting a packet
538 * Adapter = Pointer to adapter information
545 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
547 if (Adapter
->TXCurrent
< 0) return;
549 //FrameStart = Adapter->TXStart + Adapter->TXCurrent * DRIVER_BLOCK_SIZE;
550 //FrameStart = Adapter->TXStart;
551 FrameStart
= (UCHAR
)(Adapter
->TXStart
+ (UCHAR
)(Adapter
->TXCurrent
* BUFFERS_PER_TX_BUF
));
553 /* Set start of frame */
554 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_TPSR
, &Tmp
);
555 // NdisRawWritePortUchar(Adapter->IOBase + PG0_TPSR,
556 // Adapter->TXStart + Adapter->TXCurrent * DRIVER_BLOCK_SIZE);
558 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_TPSR
, FrameStart
);
559 //NDIS_DbgPrint(MID_TRACE, ("Setting start of frame to (%d).\n", FrameStart));
561 /* Set length of frame */
562 Length
= Adapter
->TXSize
[Adapter
->TXCurrent
];
563 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_TBCR0
, Length
& 0xFF);
564 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_TBCR1
, Length
>> 8);
566 /* Start transmitting */
567 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_TXP
| CR_RD2
);
569 NDIS_DbgPrint(MID_TRACE
, ("Transmitting. FrameStart (%d) TXCurrent (%d) TXStart (%d) Length (%d).\n\n",
578 static VOID
NICSetBoundaryPage(
579 PNIC_ADAPTER Adapter
)
581 * FUNCTION: Sets the boundary page on the adapter to be one less than NextPacket
583 * Adapter = Pointer to adapter information
586 if (Adapter
->NextPacket
== Adapter
->PageStart
) {
587 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_BNRY
,
588 (UCHAR
)(Adapter
->PageStop
- 1));
590 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_BNRY
,
591 (UCHAR
)(Adapter
->NextPacket
- 1));
596 static VOID
NICGetCurrentPage(
597 PNIC_ADAPTER Adapter
)
599 * FUNCTION: Retrieves the current page from the adapter
601 * Adapter = Pointer to adapter information
607 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD2
| CR_PAGE1
);
609 /* Read current page */
610 NdisRawReadPortUchar(Adapter
->IOBase
+ PG1_CURR
, &Current
);
613 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD2
| CR_PAGE0
);
615 Adapter
->CurrentPage
= Current
;
619 VOID
NICUpdateCounters(
620 PNIC_ADAPTER Adapter
)
622 * FUNCTION: Updates counters
624 * Adapter = Pointer to adapter information
629 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
631 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_CNTR0
, &Tmp
);
632 Adapter
->FrameAlignmentErrors
+= Tmp
;
634 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_CNTR1
, &Tmp
);
635 Adapter
->CrcErrors
+= Tmp
;
637 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_CNTR2
, &Tmp
);
638 Adapter
->MissedPackets
+= Tmp
;
642 VOID
NICReadDataAlign(
643 PNIC_ADAPTER Adapter
,
648 * FUNCTION: Copies data from a NIC's RAM into a buffer
650 * Adapter = Pointer to adapter information
651 * Target = Pointer to buffer to copy data into (in host memory)
652 * Source = Offset into NIC's RAM (must be an even number)
653 * Length = Number of bytes to copy from NIC's RAM (must be an even number)
661 /* Select page 0 and start the NIC */
662 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD2
| CR_PAGE0
);
664 /* Initialize RSAR0 and RSAR1 - Remote Start Address Registers */
665 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RSAR0
, (UCHAR
)(Source
& 0xFF));
666 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RSAR1
, (UCHAR
)(Source
>> 8));
668 /* Initialize RBCR0 and RBCR1 - Remote Byte Count Registers */
669 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR0
, (UCHAR
)(Count
& 0xFF));
670 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR1
, (UCHAR
)(Count
>> 8));
672 /* Select page 0, read and start the NIC */
673 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD0
| CR_PAGE0
);
675 if (Adapter
->WordMode
)
676 NdisRawReadPortBufferUshort(Adapter
->IOBase
+ NIC_DATA
, Target
, Count
>> 1);
678 NdisRawReadPortBufferUchar(Adapter
->IOBase
+ NIC_DATA
, Target
, Count
);
680 /* Wait for remote DMA to complete, but timeout after some time */
681 for (Count
= 0; Count
< 0xFFFF; Count
++) {
682 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_ISR
, &Tmp
);
686 NdisStallExecution(4);
691 NDIS_DbgPrint(MIN_TRACE
, ("Remote DMA did not complete.\n"));
694 /* Clear remote DMA bit in ISR - Interrupt Status Register */
695 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_ISR
, ISR_RDC
);
699 VOID
NICWriteDataAlign(
700 PNIC_ADAPTER Adapter
,
705 * FUNCTION: Copies data from a buffer into the NIC's RAM
707 * Adapter = Pointer to adapter information
708 * Target = Offset into NIC's RAM (must be an even number)
709 * Source = Pointer to buffer to copy data from (in host memory)
710 * Length = Number of bytes to copy from the buffer (must be an even number)
716 /* Select page 0 and start the NIC */
717 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD2
| CR_PAGE0
);
719 /* Handle read-before-write bug */
721 /* Initialize RSAR0 and RSAR1 - Remote Start Address Registers */
722 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RSAR0
, (UCHAR
)(Target
& 0xFF));
723 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RSAR1
, (UCHAR
)(Target
>> 8));
725 /* Initialize RBCR0 and RBCR1 - Remote Byte Count Registers */
726 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR0
, 0x02);
727 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR1
, 0x00);
729 /* Read and start the NIC */
730 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD0
| CR_PAGE0
);
733 NdisRawReadPortUshort(Adapter
->IOBase
+ NIC_DATA
, &Count
);
735 /* Wait for remote DMA to complete, but timeout after some time */
736 for (Count
= 0; Count
< 0xFFFF; Count
++) {
737 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_ISR
, &Tmp
);
741 NdisStallExecution(4);
746 NDIS_DbgPrint(MIN_TRACE
, ("Remote DMA did not complete.\n"));
749 /* Clear remote DMA bit in ISR - Interrupt Status Register */
750 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_ISR
, ISR_RDC
);
753 /* Now output some data */
756 /* Initialize RSAR0 and RSAR1 - Remote Start Address Registers */
757 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RSAR0
, (UCHAR
)(Target
& 0xFF));
758 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RSAR1
, (UCHAR
)(Target
>> 8));
760 /* Initialize RBCR0 and RBCR1 - Remote Byte Count Registers */
761 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR0
, (UCHAR
)(Count
& 0xFF));
762 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR1
, (UCHAR
)(Count
>> 8));
764 /* Write and start the NIC */
765 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD1
| CR_PAGE0
);
767 if (Adapter
->WordMode
)
768 NdisRawWritePortBufferUshort(Adapter
->IOBase
+ NIC_DATA
, Source
, Count
>> 1);
770 NdisRawWritePortBufferUchar(Adapter
->IOBase
+ NIC_DATA
, Source
, Count
);
772 /* Wait for remote DMA to complete, but timeout after some time */
773 for (Count
= 0; Count
< 0xFFFF; Count
++) {
774 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_ISR
, &Tmp
);
778 NdisStallExecution(4);
783 NDIS_DbgPrint(MIN_TRACE
, ("Remote DMA did not complete.\n"));
786 /* Clear remote DMA bit in ISR - Interrupt Status Register */
787 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_ISR
, ISR_RDC
);
792 PNIC_ADAPTER Adapter
,
797 * FUNCTION: Copies data from a NIC's RAM into a buffer
799 * Adapter = Pointer to adapter information
800 * Target = Pointer to buffer to copy data into (in host memory)
801 * Source = Offset into NIC's RAM
802 * Length = Number of bytes to copy from NIC's RAM
807 /* Avoid transfers to odd addresses */
809 /* Transfer one word and use the MSB */
810 NICReadDataAlign(Adapter
, &Tmp
, Source
- 1, 0x02);
811 *Target
= (UCHAR
)(Tmp
>> 8);
818 /* Transfer as many words as we can without exceeding the buffer length */
819 Tmp
= Length
& 0xFFFE;
820 NICReadDataAlign(Adapter
, (PUSHORT
)Target
, Source
, Tmp
);
822 Target
= (PUCHAR
)((ULONG_PTR
) Target
+ Tmp
);
824 /* Read one word and keep the LSB */
825 NICReadDataAlign(Adapter
, &Tmp
, Source
, 0x02);
826 *Target
= (UCHAR
)(Tmp
& 0x00FF);
828 /* Transfer the rest of the data */
829 NICReadDataAlign(Adapter
, (PUSHORT
)Target
, Source
, Length
);
834 PNIC_ADAPTER Adapter
,
839 * FUNCTION: Copies data from a buffer into NIC's RAM
841 * Adapter = Pointer to adapter information
842 * Target = Offset into NIC's RAM to store data
843 * Source = Pointer to buffer to copy data from (in host memory)
844 * Length = Number of bytes to copy from buffer
849 /* Avoid transfers to odd addresses */
852 NICReadDataAlign(Adapter
, &Tmp
, Target
- 1, 0x02);
854 /* Merge LSB with the new byte which become the new MSB */
855 Tmp
= (Tmp
& 0x00FF) | (*Source
<< 8);
857 /* Finally write the value back */
858 NICWriteDataAlign(Adapter
, Target
- 1, &Tmp
, 0x02);
860 /* Update pointers */
861 Source
= (PUCHAR
) ((ULONG_PTR
) Source
+ 1);
867 /* Transfer as many words as we can without exceeding the transfer length */
868 Tmp
= Length
& 0xFFFE;
869 NICWriteDataAlign(Adapter
, Target
, (PUSHORT
)Source
, Tmp
);
874 NICReadDataAlign(Adapter
, &Tmp
, Target
, 0x02);
876 /* Merge MSB with the new byte which become the new LSB */
877 Tmp
= (Tmp
& 0xFF00) | (*Source
);
879 /* Finally write the value back */
880 NICWriteDataAlign(Adapter
, Target
, &Tmp
, 0x02);
882 /* Transfer the rest of the data */
883 NICWriteDataAlign(Adapter
, Target
, (PUSHORT
)Source
, Length
);
887 static VOID
NICIndicatePacket(
888 PNIC_ADAPTER Adapter
)
890 * FUNCTION: Indicates a packet to the wrapper
892 * Adapter = Pointer to adapter information
897 IndicateLength
= (Adapter
->PacketHeader
.PacketLength
<
898 (Adapter
->LookaheadSize
+ DRIVER_HEADER_SIZE
))?
899 (Adapter
->PacketHeader
.PacketLength
) :
900 (Adapter
->LookaheadSize
+ DRIVER_HEADER_SIZE
);
902 /* Fill the lookahead buffer */
904 (PUCHAR
)&Adapter
->Lookahead
,
905 Adapter
->PacketOffset
+ sizeof(PACKET_HEADER
),
906 IndicateLength
+ DRIVER_HEADER_SIZE
);
908 NDIS_DbgPrint(MID_TRACE
, ("Indicating (%d) bytes.\n", IndicateLength
));
909 NDIS_DbgPrint(MID_TRACE
, ("ne2000!NICIndicatePacket: Indicating (%d) bytes.\n", IndicateLength
));
912 NDIS_DbgPrint(MAX_TRACE
, ("FRAME:\n"));
913 for (i
= 0; i
< (IndicateLength
+ 7) / 8; i
++) {
914 NDIS_DbgPrint(MAX_TRACE
, ("%02X %02X %02X %02X %02X %02X %02X %02X\n",
915 Adapter
->Lookahead
[i
*8+0],
916 Adapter
->Lookahead
[i
*8+1],
917 Adapter
->Lookahead
[i
*8+2],
918 Adapter
->Lookahead
[i
*8+3],
919 Adapter
->Lookahead
[i
*8+4],
920 Adapter
->Lookahead
[i
*8+5],
921 Adapter
->Lookahead
[i
*8+6],
922 Adapter
->Lookahead
[i
*8+7]));
926 if (IndicateLength
>= DRIVER_HEADER_SIZE
) {
927 NDIS_DbgPrint(MAX_TRACE
,("Adapter->MiniportAdapterHandle: %x\n",
928 Adapter
->MiniportAdapterHandle
));
929 NdisMEthIndicateReceive(Adapter
->MiniportAdapterHandle
,
931 (PVOID
)&Adapter
->Lookahead
,
933 (PVOID
)&Adapter
->Lookahead
[DRIVER_HEADER_SIZE
],
934 IndicateLength
- DRIVER_HEADER_SIZE
,
935 Adapter
->PacketHeader
.PacketLength
- DRIVER_HEADER_SIZE
);
937 NdisMEthIndicateReceive(Adapter
->MiniportAdapterHandle
,
939 (PVOID
)&Adapter
->Lookahead
,
948 static VOID
NICReadPacket(
949 PNIC_ADAPTER Adapter
)
951 * FUNCTION: Reads a full packet from the receive buffer ring
953 * Adapter = Pointer to adapter information
956 BOOLEAN SkipPacket
= FALSE
;
958 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
960 /* Get the header of the next packet in the receive ring */
961 Adapter
->PacketOffset
= Adapter
->NextPacket
<< 8;
963 (PUCHAR
)&Adapter
->PacketHeader
,
964 Adapter
->PacketOffset
,
965 sizeof(PACKET_HEADER
));
967 NDIS_DbgPrint(MAX_TRACE
, ("HEADER: (Status) (0x%X)\n", Adapter
->PacketHeader
.Status
));
968 NDIS_DbgPrint(MAX_TRACE
, ("HEADER: (NextPacket) (0x%X)\n", Adapter
->PacketHeader
.NextPacket
));
969 NDIS_DbgPrint(MAX_TRACE
, ("HEADER: (PacketLength) (0x%X)\n", Adapter
->PacketHeader
.PacketLength
));
971 if (Adapter
->PacketHeader
.PacketLength
< 64 ||
972 Adapter
->PacketHeader
.PacketLength
> 1518) { /* XXX I don't think the CRC will show up... should be 1514 */
973 NDIS_DbgPrint(MAX_TRACE
, ("Bogus packet size (%d).\n",
974 Adapter
->PacketHeader
.PacketLength
));
980 Adapter
->NextPacket
= Adapter
->CurrentPage
;
982 NDIS_DbgPrint(MAX_TRACE
,("Adapter->MiniportAdapterHandle: %x\n",
983 Adapter
->MiniportAdapterHandle
));
984 NICIndicatePacket(Adapter
);
986 /* Go to the next free buffer in receive ring */
987 Adapter
->NextPacket
= Adapter
->PacketHeader
.NextPacket
;
990 /* Update boundary page */
991 NICSetBoundaryPage(Adapter
);
995 static VOID
NICWritePacket(
996 PNIC_ADAPTER Adapter
)
998 * FUNCTION: Writes a full packet to the transmit buffer ring
1000 * Adapter = Pointer to adapter information
1002 * There must be enough free buffers available in the transmit buffer ring.
1003 * The packet is taken from the head of the transmit queue and the position
1004 * into the transmit buffer ring is taken from TXNext
1007 PNDIS_BUFFER SrcBuffer
;
1008 UINT BytesToCopy
, SrcSize
, DstSize
;
1014 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1016 TXStart
= Adapter
->TXStart
* DRIVER_BLOCK_SIZE
;
1017 TXStop
= (Adapter
->TXStart
+ Adapter
->TXCount
) * DRIVER_BLOCK_SIZE
;
1019 NdisQueryPacket(Adapter
->TXQueueHead
,
1023 &Adapter
->TXSize
[Adapter
->TXNext
]);
1025 NDIS_DbgPrint(MID_TRACE
, ("Packet (%d) is now size (%d).\n",
1027 Adapter
->TXSize
[Adapter
->TXNext
]));
1029 NdisQueryBuffer(SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
);
1031 DstData
= TXStart
+ Adapter
->TXNext
* DRIVER_BLOCK_SIZE
;
1032 DstSize
= TXStop
- DstData
;
1034 /* Start copying the data */
1036 BytesToCopy
= (SrcSize
< DstSize
)? SrcSize
: DstSize
;
1038 NICWriteData(Adapter
, DstData
, SrcData
, BytesToCopy
);
1040 SrcData
= (PUCHAR
)((ULONG_PTR
) SrcData
+ BytesToCopy
);
1041 SrcSize
-= BytesToCopy
;
1042 DstData
+= BytesToCopy
;
1043 DstSize
-= BytesToCopy
;
1046 /* No more bytes in source buffer. Proceed to
1047 the next buffer in the source buffer chain */
1048 NdisGetNextBuffer(SrcBuffer
, &SrcBuffer
);
1052 NdisQueryBuffer(SrcBuffer
, (PVOID
)&SrcData
, &SrcSize
);
1056 /* Wrap around the end of the transmit buffer ring */
1058 DstSize
= Adapter
->TXCount
* DRIVER_BLOCK_SIZE
;
1064 static BOOLEAN
NICPrepareForTransmit(
1065 PNIC_ADAPTER Adapter
)
1067 * FUNCTION: Prepares a packet for transmission
1069 * Adapter = Pointer to adapter information
1071 * There must be at least one packet in the transmit queue
1073 * TRUE if a packet was prepared, FALSE if not
1078 PNDIS_PACKET Packet
;
1080 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1082 /* Calculate number of buffers needed to transmit packet */
1083 NdisQueryPacket(Adapter
->TXQueueHead
,
1089 BufferCount
= (Length
+ DRIVER_BLOCK_SIZE
- 1) / DRIVER_BLOCK_SIZE
;
1091 if (BufferCount
> Adapter
->TXFree
) {
1092 NDIS_DbgPrint(MID_TRACE
, ("No transmit resources. Have (%d) buffers, need (%d).\n",
1093 Adapter
->TXFree
, BufferCount
));
1094 /* We don't have the resources to transmit this packet right now */
1098 /* Write the packet to the card */
1099 NICWritePacket(Adapter
);
1101 /* If the NIC is not transmitting, reset the current transmit pointer */
1102 if (Adapter
->TXCurrent
== -1)
1103 Adapter
->TXCurrent
= Adapter
->TXNext
;
1105 Adapter
->TXNext
= (Adapter
->TXNext
+ BufferCount
) % Adapter
->TXCount
;
1106 Adapter
->TXFree
-= BufferCount
;
1108 /* Remove the packet from the queue */
1109 Packet
= Adapter
->TXQueueHead
;
1110 Adapter
->TXQueueHead
= RESERVED(Packet
)->Next
;
1112 if (Packet
== Adapter
->TXQueueTail
)
1113 Adapter
->TXQueueTail
= NULL
;
1115 /* Assume the transmit went well */
1116 NdisMSendComplete(Adapter
->MiniportAdapterHandle
,
1118 NDIS_STATUS_SUCCESS
);
1125 PNIC_ADAPTER Adapter
)
1127 * FUNCTION: Starts transmitting packets in the transmit queue
1129 * Adapter = Pointer to adapter information
1131 * There must be at least one packet in the transmit queue
1134 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1136 if (Adapter
->TXCurrent
== -1) {
1137 /* NIC is not transmitting, so start transmitting now */
1139 /* Load next packet onto the card, and start transmitting */
1140 if (NICPrepareForTransmit(Adapter
))
1141 NICStartTransmit(Adapter
);
1146 static VOID
HandleReceive(
1147 PNIC_ADAPTER Adapter
)
1149 * FUNCTION: Handles reception of a packet
1151 * Adapter = Pointer to adapter information
1153 * Buffer overflows are also handled here
1160 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1162 Adapter
->DoneIndicating
= FALSE
;
1165 NICGetCurrentPage(Adapter
);
1167 if (Adapter
->BufferOverflow
) {
1169 NDIS_DbgPrint(MID_TRACE
, ("Receive ring overflow.\n"));
1171 /* Select page 0 and stop the NIC */
1172 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STP
| CR_RD2
| CR_PAGE0
);
1174 /* Clear RBCR0,RBCR1 - Remote Byte Count Registers */
1175 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR0
, 0x00);
1176 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_RBCR1
, 0x00);
1178 /* Wait for ISR_RST to be set, but timeout after 2ms */
1179 for (i
= 0; i
< 4; i
++) {
1180 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_ISR
, &Tmp
);
1184 NdisStallExecution(500);
1189 NDIS_DbgPrint(MIN_TRACE
, ("NIC was not reset after 2ms.\n"));
1192 if ((Adapter
->InterruptStatus
& (ISR_PTX
| ISR_TXE
)) == 0) {
1193 /* We may need to restart the transmitter */
1194 Adapter
->TransmitPending
= TRUE
;
1197 /* Initialize TCR - Transmit Configuration Register to loopback mode 1 */
1198 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_TCR
, TCR_LOOP
);
1201 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_CR
, CR_STA
| CR_RD2
);
1205 Adapter
->BufferOverflow
= FALSE
;
1208 if (Adapter
->ReceiveError
) {
1209 NDIS_DbgPrint(MID_TRACE
, ("Receive error.\n"));
1211 /* Skip this packet */
1212 Adapter
->NextPacket
= Adapter
->CurrentPage
;
1213 NICSetBoundaryPage(Adapter
);
1215 Adapter
->ReceiveError
= FALSE
;
1219 NICGetCurrentPage(Adapter
);
1221 NDIS_DbgPrint(MID_TRACE
, ("Current page (0x%X) NextPacket (0x%X).\n",
1222 Adapter
->CurrentPage
,
1223 Adapter
->NextPacket
));
1225 if (Adapter
->CurrentPage
== Adapter
->NextPacket
) {
1226 NDIS_DbgPrint(MID_TRACE
, ("No more packets.\n"));
1229 NDIS_DbgPrint(MID_TRACE
, ("Got a packet in the receive ring.\n"));
1231 NDIS_DbgPrint(MAX_TRACE
,("Adapter->MiniportAdapterHandle: %x\n",
1232 Adapter
->MiniportAdapterHandle
));
1233 /* Read packet from receive buffer ring */
1234 NICReadPacket(Adapter
);
1236 Adapter
->DoneIndicating
= TRUE
;
1239 if (PacketCount
== 10) {
1240 /* Don't starve transmit interrupts */
1246 if ((Adapter
->TransmitPending
) && (Adapter
->TXCurrent
!= -1)) {
1247 NDIS_DbgPrint(MID_TRACE
, ("Retransmitting current packet at (%d).\n", Adapter
->TXCurrent
));
1248 /* Retransmit packet */
1249 NICStartTransmit(Adapter
);
1250 Adapter
->TransmitPending
= FALSE
;
1253 if (Adapter
->DoneIndicating
)
1254 NdisMEthIndicateReceiveComplete(Adapter
->MiniportAdapterHandle
);
1258 static VOID
HandleTransmit(
1259 PNIC_ADAPTER Adapter
)
1261 * FUNCTION: Handles transmission of a packet
1263 * Adapter = Pointer to adapter information
1269 // PIP_PACKET pIPPacket;
1270 // pIPPacket = (PIP_PACKET)
1271 // DisplayIPPacket(pIPPacket);
1273 if (Adapter
->TransmitError
) {
1274 /* FIXME: Retransmit now or let upper layer protocols handle retransmit? */
1275 Adapter
->TransmitError
= FALSE
;
1278 /* Free transmit buffers */
1279 Length
= Adapter
->TXSize
[Adapter
->TXCurrent
];
1280 BufferCount
= (Length
+ DRIVER_BLOCK_SIZE
- 1) / DRIVER_BLOCK_SIZE
;
1282 NDIS_DbgPrint(MID_TRACE
, ("Freeing (%d) buffers at (%d).\n",
1284 Adapter
->TXCurrent
));
1286 Adapter
->TXFree
+= BufferCount
;
1287 Adapter
->TXSize
[Adapter
->TXCurrent
] = 0;
1288 Adapter
->TXCurrent
= (Adapter
->TXCurrent
+ BufferCount
) % Adapter
->TXCount
;
1290 if (Adapter
->TXSize
[Adapter
->TXCurrent
] == 0) {
1291 NDIS_DbgPrint(MID_TRACE
, ("No more packets in transmit buffer.\n"));
1293 Adapter
->TXCurrent
= -1;
1296 if (Adapter
->TXQueueTail
) {
1297 if (NICPrepareForTransmit(Adapter
))
1298 NICStartTransmit(Adapter
);
1303 VOID NTAPI
MiniportHandleInterrupt(
1304 IN NDIS_HANDLE MiniportAdapterContext
)
1306 * FUNCTION: Handler for deferred processing of interrupts
1308 * MiniportAdapterContext = Pointer to adapter context area
1310 * Interrupt Service Register is read to determine which interrupts
1311 * are pending. All pending interrupts are handled
1317 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
1319 ISRMask
= Adapter
->InterruptMask
;
1320 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_ISR
, &ISRValue
);
1322 NDIS_DbgPrint(MID_TRACE
, ("ISRValue (0x%X).\n", ISRValue
));
1324 Adapter
->InterruptStatus
|= (ISRValue
& ISRMask
);
1326 if (ISRValue
!= 0x00)
1327 /* Acknowledge interrupts */
1328 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_ISR
, ISRValue
);
1331 while (Adapter
->InterruptStatus
!= 0x00) {
1333 NDIS_DbgPrint(MID_TRACE
, ("Adapter->InterruptStatus (0x%X) Mask (0x%X).\n",
1334 Adapter
->InterruptStatus
, Mask
));
1336 /* Find next interrupt type */
1337 while (((Adapter
->InterruptStatus
& Mask
) == 0) && (Mask
< ISRMask
))
1340 switch (Adapter
->InterruptStatus
& Mask
) {
1342 NDIS_DbgPrint(MID_TRACE
, ("Overflow interrupt.\n"));
1343 /* Overflow. Handled almost the same way as a receive interrupt */
1344 Adapter
->BufferOverflow
= TRUE
;
1346 NDIS_DbgPrint(MAX_TRACE
,("Adapter->MiniportAdapterHandle: %x\n",
1347 Adapter
->MiniportAdapterHandle
));
1348 if(Adapter
->MiniportAdapterHandle
)
1349 HandleReceive(Adapter
);
1351 NDIS_DbgPrint(MAX_TRACE
,("No miniport adapter yet\n"));
1353 Adapter
->InterruptStatus
&= ~ISR_OVW
;
1357 NDIS_DbgPrint(MID_TRACE
, ("Receive error interrupt.\n"));
1358 NICUpdateCounters(Adapter
);
1360 Adapter
->ReceiveError
= TRUE
;
1363 NDIS_DbgPrint(MID_TRACE
, ("Receive interrupt.\n"));
1365 NDIS_DbgPrint(MAX_TRACE
,("Adapter->MiniportAdapterHandle: %x\n",
1366 Adapter
->MiniportAdapterHandle
));
1367 if(Adapter
->MiniportAdapterHandle
)
1368 HandleReceive(Adapter
);
1370 NDIS_DbgPrint(MAX_TRACE
,("No miniport adapter yet\n"));
1372 Adapter
->InterruptStatus
&= ~(ISR_PRX
| ISR_RXE
);
1376 NDIS_DbgPrint(MID_TRACE
, ("Transmit error interrupt.\n"));
1377 NICUpdateCounters(Adapter
);
1379 Adapter
->TransmitError
= TRUE
;
1382 NDIS_DbgPrint(MID_TRACE
, ("Transmit interrupt.\n"));
1384 HandleTransmit(Adapter
);
1386 Adapter
->InterruptStatus
&= ~(ISR_PTX
| ISR_TXE
);
1390 NDIS_DbgPrint(MID_TRACE
, ("Counter interrupt.\n"));
1391 /* Counter overflow. Read counters from the NIC */
1392 NICUpdateCounters(Adapter
);
1394 Adapter
->InterruptStatus
&= ~ISR_CNT
;
1398 NDIS_DbgPrint(MID_TRACE
, ("Unknown interrupt. Adapter->InterruptStatus (0x%X).\n", Adapter
->InterruptStatus
));
1399 Adapter
->InterruptStatus
&= ~Mask
;
1405 /* Check if new interrupts are generated */
1407 NdisRawReadPortUchar(Adapter
->IOBase
+ PG0_ISR
, &ISRValue
);
1409 NDIS_DbgPrint(MID_TRACE
, ("ISRValue (0x%X).\n", ISRValue
));
1411 Adapter
->InterruptStatus
|= (ISRValue
& ISRMask
);
1413 if (ISRValue
!= 0x00) {
1414 /* Acknowledge interrupts */
1415 NdisRawWritePortUchar(Adapter
->IOBase
+ PG0_ISR
, ISRValue
);
1420 NICEnableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);