2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1995-1996 NeXT Software, Inc.
25 * Implementation for hardware dependent (relatively) code
26 * for the Mace Ethernet controller.
35 #include <IOKit/assert.h>
36 #include <IOKit/system.h>
37 #include <IOKit/IOLib.h>
38 #include "MaceEnetPrivate.h"
41 /*****************************************************************************
46 typedef unsigned long long ns_time_t
; /* nanoseconds! */
48 #define NSEC_PER_SEC 1000000000
51 _IOGetTimestamp(ns_time_t
*nsp
)
56 *nsp
= ((ns_time_t
)now
.tv_sec
* NSEC_PER_SEC
) + now
.tv_nsec
;
60 * Find a physical address (if any) for the specified virtual address.
62 * Note: what about vm_offset_t kvtophys(vm_offset_t va)
64 static IOReturn
_IOPhysicalFromVirtual(
65 vm_address_t virtualAddress
,
66 unsigned *physicalAddress
)
68 *physicalAddress
= pmap_extract(kernel_pmap
, virtualAddress
);
69 if(*physicalAddress
== 0) {
70 return kIOReturnBadArgument
;
73 return kIOReturnSuccess
;
77 // From osfmk/ppc/pmap.h
80 extern void invalidate_dcache(vm_offset_t va
, unsigned length
, boolean_t phys
);
81 extern void flush_dcache(vm_offset_t va
, unsigned length
, boolean_t phys
);
85 invalidate_cache_v(vm_offset_t va
, unsigned length
)
87 invalidate_dcache(va
, length
, 0);
91 flush_cache_v(vm_offset_t va
, unsigned length
)
93 flush_dcache(va
, length
, 0);
96 /****************************************************************************/
98 static IODBDMADescriptor dbdmaCmd_Nop
;
99 static IODBDMADescriptor dbdmaCmd_NopWInt
;
100 static IODBDMADescriptor dbdmaCmd_LoadXFS
;
101 static IODBDMADescriptor dbdmaCmd_LoadIntwInt
;
102 static IODBDMADescriptor dbdmaCmd_Stop
;
103 static IODBDMADescriptor dbdmaCmd_Branch
;
106 static u_int8_t
reverseBitOrder(u_int8_t data
)
111 for ( i
=0; i
< 8; i
++ )
114 if (data
& 1) val
|= 1;
121 * Function: IOMallocPage
124 * Returns a pointer to a page-aligned memory block of size >= PAGE_SIZE
127 * Actual pointer and size of block returned in actual_ptr and actual_size.
128 * Use these as arguments to kfree: kfree(*actual_ptr, *actual_size);
131 IOMallocPage(int request_size
, void ** actual_ptr
, u_int
* actual_size
)
135 *actual_size
= round_page(request_size
) + PAGE_SIZE
;
136 mem_ptr
= IOMalloc(*actual_size
);
139 *actual_ptr
= mem_ptr
;
140 return ((void *)round_page(mem_ptr
));
146 bool MaceEnet::_allocateMemory()
149 unsigned char * virtAddr
;
155 * Calculate total space for DMA channel commands
157 dbdmaSize
= round_page(
158 RX_RING_LENGTH
* sizeof(enet_dma_cmd_t
) +
159 TX_RING_LENGTH
* sizeof(enet_txdma_cmd_t
) +
160 2 * sizeof(IODBDMADescriptor
) );
163 * Allocate required memory
165 dmaMemory
.size
= dbdmaSize
;
166 dmaMemory
.ptr
= (void *)IOMallocPage(
172 dmaCommands
= (unsigned char *) dmaMemory
.ptr
;
174 IOLog( "Mace: Cant allocate channel DBDMA commands\n\r" );
179 * If we needed more than one page, then make sure we received
182 n
= (dbdmaSize
- PAGE_SIZE
) / PAGE_SIZE
;
183 _IOPhysicalFromVirtual((vm_address_t
) dmaCommands
, &physBase
);
185 virtAddr
= (unsigned char *) dmaCommands
;
186 for( i
=0; i
< n
; i
++, virtAddr
+= PAGE_SIZE
)
188 _IOPhysicalFromVirtual( (vm_address_t
) virtAddr
, &physAddr
);
189 if (physAddr
!= (physBase
+ i
* PAGE_SIZE
) )
191 IOLog("Mace: Cannot allocate contiguous memory for DBDMA "
198 * Setup the receive ring pointers
200 rxDMACommands
= (enet_dma_cmd_t
*)dmaCommands
;
201 rxMaxCommand
= RX_RING_LENGTH
;
204 * Setup the transmit ring pointers
206 txDMACommands
= (enet_txdma_cmd_t
*)(
208 RX_RING_LENGTH
* sizeof(enet_dma_cmd_t
) +
209 sizeof(IODBDMADescriptor
));
211 txMaxCommand
= TX_RING_LENGTH
;
214 * Setup pre-initialized DBDMA commands
216 IOMakeDBDMADescriptor( (&dbdmaCmd_Nop
),
225 IOMakeDBDMADescriptor( (&dbdmaCmd_NopWInt
),
234 UInt32 ioBaseEnetPhys
= maps
[MEMORY_MAP_ENET_INDEX
]->getPhysicalAddress();
236 IOMakeDBDMADescriptor( (&dbdmaCmd_LoadXFS
),
243 ((int)ioBaseEnetPhys
+ kXmtFS
) );
245 IOMakeDBDMADescriptor( (&dbdmaCmd_LoadIntwInt
),
252 ((int)ioBaseEnetPhys
+ kIntReg
) );
254 IOMakeDBDMADescriptor( (&dbdmaCmd_Stop
),
263 IOMakeDBDMADescriptor( (&dbdmaCmd_Branch
),
275 /*-------------------------------------------------------------------------
277 * Setup the Transmit Ring
278 * -----------------------
279 * Each transmit ring entry consists of two words to transmit data from buffer
280 * segments (possibly) spanning a page boundary. This is followed by two DMA
281 * commands which read transmit frame status and interrupt status from the Mace
282 * chip. The last DMA command in each transmit ring entry generates a host
283 * interrupt. The last entry in the ring is followed by a DMA branch to the
285 *-------------------------------------------------------------------------*/
287 bool MaceEnet::_initTxRing()
293 * Clear the transmit DMA command memory
295 bzero( (void *)txDMACommands
, sizeof(enet_txdma_cmd_t
) * txMaxCommand
);
300 * DMA Channel commands 2,3 are the same for all DBDMA entries on transmit.
301 * Initialize them now.
303 for( i
=0; i
< txMaxCommand
; i
++ )
305 txDMACommands
[i
].desc_seg
[2] = dbdmaCmd_LoadXFS
;
306 txDMACommands
[i
].desc_seg
[3] = dbdmaCmd_LoadIntwInt
;
310 * Put a DMA Branch command after the last entry in the transmit ring.
311 * Set the branch address to the physical address of the start of the
314 txDMACommands
[txMaxCommand
].desc_seg
[0] = dbdmaCmd_Branch
;
316 kr
= _IOPhysicalFromVirtual( (vm_address_t
) txDMACommands
,
317 (u_int32_t
*)&txDMACommandsPhys
);
318 if ( kr
!= kIOReturnSuccess
)
320 IOLog("Mace: Bad Tx DBDMA command buf - %08x\n\r",
321 (u_int32_t
)txDMACommands
);
323 IOSetCCCmdDep( &txDMACommands
[txMaxCommand
].desc_seg
[0],
327 * Set the Transmit DMA Channel pointer to the first entry in the
330 IOSetDBDMACommandPtr( ioBaseEnetTxDMA
, txDMACommandsPhys
);
333 * Push the DMA channel words into physical memory.
335 flush_cache_v( (vm_offset_t
)txDMACommands
,
336 txMaxCommand
*sizeof(enet_txdma_cmd_t
) + sizeof(IODBDMADescriptor
));
341 /*-------------------------------------------------------------------------
343 * Setup the Receive ring
344 * ----------------------
345 * Each receive ring entry consists of two DMA commands to receive data
346 * into a network buffer (possibly) spanning a page boundary. The second
347 * DMA command in each entry generates a host interrupt.
348 * The last entry in the ring is followed by a DMA branch to the first
351 *-------------------------------------------------------------------------*/
353 bool MaceEnet::_initRxRing()
360 * Clear the receive DMA command memory
362 bzero( (void *)rxDMACommands
, sizeof(enet_dma_cmd_t
) * rxMaxCommand
);
364 kr
= _IOPhysicalFromVirtual( (vm_address_t
) rxDMACommands
,
365 (u_int32_t
*)&rxDMACommandsPhys
);
366 if ( kr
!= kIOReturnSuccess
)
368 IOLog("Mace: Bad Rx DBDMA command buf - %08x\n\r",
369 (u_int32_t
)rxDMACommands
);
374 * Allocate a receive buffer for each entry in the Receive ring
376 for (i
= 0; i
< rxMaxCommand
-1; i
++)
380 rxMbuf
[i
] = allocatePacket(NETWORK_BUFSIZE
);
384 IOLog("Mace: allocatePacket failed in _initRxRing()\n\r");
390 * Set the DMA commands for the ring entry to transfer data to the
393 status
= _updateDescriptorFromMbuf(rxMbuf
[i
], &rxDMACommands
[i
], true);
396 IOLog("Mace: Cant map mbuf to physical memory in _initRxRing\n\r");
402 * Set the receive queue head to point to the first entry in the ring.
403 * Set the receive queue tail to point to a DMA Stop command after the
409 rxDMACommands
[i
].desc_seg
[0] = dbdmaCmd_Stop
;
410 rxDMACommands
[i
].desc_seg
[1] = dbdmaCmd_Nop
;
413 * Setup a DMA branch command after the stop command
416 rxDMACommands
[i
].desc_seg
[0] = dbdmaCmd_Branch
;
418 IOSetCCCmdDep( &rxDMACommands
[i
].desc_seg
[0], rxDMACommandsPhys
);
421 * Set DMA command pointer to first receive entry
423 IOSetDBDMACommandPtr( ioBaseEnetRxDMA
, rxDMACommandsPhys
);
426 * Push DMA commands to physical memory
428 flush_cache_v( (vm_offset_t
)&rxDMACommands
[rxCommandTail
],
429 2 * sizeof(enet_dma_cmd_t
) );
434 /*-------------------------------------------------------------------------
438 *-------------------------------------------------------------------------*/
440 void MaceEnet::_startChip()
442 WriteMaceRegister( ioBaseEnet
, kMacCC
, kMacCCEnXmt
| kMacCCEnRcv
);
444 // enable rx dma channel
445 IODBDMAContinue( ioBaseEnetRxDMA
);
448 /*-------------------------------------------------------------------------
452 *-------------------------------------------------------------------------*/
454 void MaceEnet::_resetChip()
459 * Mace errata - chip reset does not clear pending interrupts
461 ReadMaceRegister( ioBaseEnet
, kIntReg
);
463 IODBDMAReset( ioBaseEnetRxDMA
);
464 IODBDMAReset( ioBaseEnetTxDMA
);
466 IOSetDBDMAWaitSelect( ioBaseEnetTxDMA
,
467 IOSetDBDMAChannelControlBits( kdbdmaS5
) );
469 IOSetDBDMABranchSelect( ioBaseEnetRxDMA
,
470 IOSetDBDMAChannelControlBits( kdbdmaS6
) );
472 IOSetDBDMAInterruptSelect( ioBaseEnetRxDMA
,
473 IOSetDBDMAChannelControlBits( kdbdmaS6
) );
475 WriteMaceRegister( ioBaseEnet
, kBIUCC
, kBIUCCSWRst
);
478 regValue
= ReadMaceRegister( ioBaseEnet
, kBIUCC
);
480 while( regValue
& kBIUCCSWRst
);
483 /*-------------------------------------------------------------------------
487 *-------------------------------------------------------------------------*/
489 bool MaceEnet::_initChip()
491 volatile u_int16_t regValue
;
494 _disableAdapterInterrupts();
496 chipId
= ReadMaceRegister( ioBaseEnet
, kMaceChipId0
);
497 chipId
|= ReadMaceRegister( ioBaseEnet
, kMaceChipId1
) << 8;
500 * Turn off ethernet header stripping
502 regValue
= ReadMaceRegister( ioBaseEnet
, kRcvFC
);
503 regValue
&= ~kRcvFCAStrpRcv
;
504 WriteMaceRegister( ioBaseEnet
, kRcvFC
, regValue
);
507 * Set Mace destination address.
509 if ( chipId
!= kMaceRevisionA2
)
511 WriteMaceRegister( ioBaseEnet
, kIAC
, kIACAddrChg
| kIACPhyAddr
);
514 regValue
= ReadMaceRegister( ioBaseEnet
, kIAC
);
516 while( regValue
& kIACAddrChg
);
520 WriteMaceRegister( ioBaseEnet
, kIAC
, kIACPhyAddr
);
523 for (i
=0; i
< sizeof(IOEthernetAddress
); i
++ )
525 WriteMaceRegister( ioBaseEnet
, kPADR
,
526 reverseBitOrder(((unsigned char *)ioBaseEnetROM
)[i
<<4]) );
530 * Clear logical address (multicast) filter
532 if ( chipId
!= kMaceRevisionA2
)
534 WriteMaceRegister( ioBaseEnet
, kIAC
, kIACAddrChg
| kIACLogAddr
);
537 regValue
= ReadMaceRegister( ioBaseEnet
, kIAC
);
539 while( regValue
& kIACAddrChg
);
543 WriteMaceRegister( ioBaseEnet
, kIAC
, kIACLogAddr
);
546 for (i
= 0; i
< 8; i
++ )
548 WriteMaceRegister( ioBaseEnet
, kLADRF
, 0 );
552 * Enable ethernet transceiver
554 WriteMaceRegister( ioBaseEnet
, kPLSCC
, kPLSCCPortSelGPSI
| kPLSCCEnSts
);
560 /*-------------------------------------------------------------------------
564 *-------------------------------------------------------------------------*/
566 void MaceEnet::_restartChip()
569 * Shutdown DMA channels
575 * Get the silicon's attention
581 * Restore multicast settings
583 _updateHashTableMask();
587 _setPromiscuousMode(kIOEnetPromiscuousModeOn
);
591 * Enable receiver and transmitter
594 _enableAdapterInterrupts();
597 * Restart transmit DMA
599 IODBDMAContinue( ioBaseEnetTxDMA
);
602 /*-------------------------------------------------------------------------
604 * Orderly stop of receive DMA.
607 *-------------------------------------------------------------------------*/
609 void MaceEnet::_stopReceiveDMA()
619 * Stop the receiver and allow any frame receive in progress to complete
621 MacCCReg
= ReadMaceRegister( ioBaseEnet
, kMacCC
);
622 WriteMaceRegister( ioBaseEnet
, kMacCC
, MacCCReg
& ~kMacCCEnRcv
);
623 IODelay( RECEIVE_QUIESCE_uS
);
626 * Capture channel status and pause the dma channel.
628 dmaStatus
= IOGetDBDMAChannelStatus( ioBaseEnetRxDMA
);
629 IODBDMAPause( ioBaseEnetRxDMA
);
632 * Read the command pointer and convert it to a byte offset into the
635 dmaCmdPtr
= IOGetDBDMACommandPtr( ioBaseEnetRxDMA
);
636 dmaIndex
= (dmaCmdPtr
- rxDMACommandsPhys
);
639 * If the channel status is DEAD, the DMA pointer is pointing to the
642 if ( dmaStatus
& kdbdmaDead
)
644 dmaIndex
-= sizeof(IODBDMADescriptor
);
648 * Convert channel program offset to command index
650 dmaIndex
= dmaIndex
/ sizeof(enet_dma_cmd_t
);
651 if ( dmaIndex
>= rxMaxCommand
) dmaIndex
= 0;
654 * The DMA controller doesnt like being stopped before transferring any
657 * When we do so it pollutes up to 16-bytes aligned to the nearest (lower)
658 * 16-byte boundary. This corruption can be outside the data transfer area
659 * of the mbuf, so we capture and then restore these bytes after stopping
663 if ( rxMbuf
[dmaIndex
] )
665 p
= mtod(rxMbuf
[dmaIndex
], u_int8_t
*);
668 (u_int32_t
)p
&= ~0x0f;
672 bcopy( p
, tmpBuf
, 16 );
675 IODBDMAReset( ioBaseEnetRxDMA
);
679 bcopy( tmpBuf
, p
, 16 );
683 * Reset the dma channel pointer to the nearest command index
685 dmaCmdPtr
= rxDMACommandsPhys
+ sizeof(enet_dma_cmd_t
) * dmaIndex
;
686 IOSetDBDMACommandPtr( ioBaseEnetRxDMA
, dmaCmdPtr
);
689 /*-------------------------------------------------------------------------
693 *-------------------------------------------------------------------------*/
695 void MaceEnet::_stopTransmitDMA()
703 * Stop the transmitter and allow any frame transmit in progress to abort
705 MacCCReg
= ReadMaceRegister( ioBaseEnet
, kMacCC
);
706 WriteMaceRegister( ioBaseEnet
, kMacCC
, MacCCReg
& ~kMacCCEnXmt
);
707 IODelay( TRANSMIT_QUIESCE_uS
);
710 * Capture channel status and pause the dma channel.
712 dmaStatus
= IOGetDBDMAChannelStatus( ioBaseEnetTxDMA
);
713 IODBDMAPause( ioBaseEnetTxDMA
);
716 * Read the command pointer and convert it to a byte offset into the
719 dmaCmdPtr
= IOGetDBDMACommandPtr( ioBaseEnetTxDMA
);
720 dmaIndex
= (dmaCmdPtr
- txDMACommandsPhys
);
723 * If the channel status is DEAD, the DMA pointer is pointing to the
726 if ( dmaStatus
& kdbdmaDead
)
728 dmaIndex
-= sizeof(IODBDMADescriptor
);
732 * Convert channel program offset to command index
734 dmaIndex
= dmaIndex
/ sizeof(enet_txdma_cmd_t
);
735 if ( dmaIndex
>= txMaxCommand
) dmaIndex
= 0;
737 IODBDMAReset( ioBaseEnetTxDMA
);
740 * Reset the dma channel pointer to the nearest command index
742 dmaCmdPtr
= txDMACommandsPhys
+ sizeof(enet_txdma_cmd_t
) * dmaIndex
;
743 IOSetDBDMACommandPtr( ioBaseEnetTxDMA
, dmaCmdPtr
);
746 /*-------------------------------------------------------------------------
750 *-------------------------------------------------------------------------*/
752 void MaceEnet::_disableAdapterInterrupts()
754 WriteMaceRegister( ioBaseEnet
, kIntMask
, 0xFF );
757 /*-------------------------------------------------------------------------
759 * _enableAdapterInterrupts
761 * It appears to make the Mace chip work properly with the DBDMA channel
762 * we need to leave the transmit interrupt unmasked at the chip. This
763 * is weird, but that's what happens when you try to glue a chip that
764 * wasn't intended to work with a DMA engine on to a DMA.
766 *-------------------------------------------------------------------------*/
768 void MaceEnet::_enableAdapterInterrupts()
772 regValue
= ReadMaceRegister( ioBaseEnet
, kIntMask
);
773 regValue
&= ~kIntMaskXmtInt
;
774 WriteMaceRegister( ioBaseEnet
, kIntMask
, regValue
);
776 ReadMaceRegister( ioBaseEnet
, kXmtFS
);
777 ReadMaceRegister( ioBaseEnet
, kIntReg
);
780 /*-------------------------------------------------------------------------
784 *-------------------------------------------------------------------------*/
786 bool MaceEnet::_transmitPacket(struct mbuf
* packet
)
788 enet_dma_cmd_t tmpCommand
;
792 * Check for room on the transmit ring. There should always be space
793 * since it is the responsibility of the caller to verify this before
794 * calling _transmitPacket.
796 * Get a copy of the DMA transfer commands in a temporary buffer.
797 * The new DMA command is written into the channel program so that the
798 * command word for the old Stop command is overwritten last. This prevents
799 * the DMA engine from executing a partially written channel command.
801 i
= txCommandTail
+ 1;
802 if ( i
>= txMaxCommand
) i
= 0;
804 if ( (i
== txCommandHead
) ||
805 !_updateDescriptorFromMbuf(packet
, &tmpCommand
, false))
807 IOLog("Mace: Freeing transmit packet eh?\n\r");
808 if (packet
!= txDebuggerPkt
)
814 * txCommandTail points to the current DMA Stop command for the channel.
815 * We are now creating a new DMA Stop command in the next slot in the
816 * transmit ring. The previous DMA Stop command will be overwritten with
817 * the DMA commands to transfer the new mbuf.
819 txDMACommands
[i
].desc_seg
[0] = dbdmaCmd_Stop
;
820 txDMACommands
[i
].desc_seg
[1] = dbdmaCmd_Nop
;
822 flush_cache_v( (vm_offset_t
)&txDMACommands
[i
], sizeof(enet_dma_cmd_t
) );
824 bcopy( ((u_int32_t
*)&tmpCommand
)+1,
825 ((u_int32_t
*)&txDMACommands
[txCommandTail
])+1,
826 sizeof(enet_dma_cmd_t
)-sizeof(u_int32_t
) );
828 flush_cache_v( (vm_offset_t
)&txDMACommands
[txCommandTail
],
829 sizeof(enet_dma_cmd_t
) );
831 txMbuf
[txCommandTail
] = packet
;
832 txDMACommands
[txCommandTail
].desc_seg
[0].operation
=
833 tmpCommand
.desc_seg
[0].operation
;
835 flush_cache_v( (vm_offset_t
)&txDMACommands
[txCommandTail
],
836 sizeof(enet_dma_cmd_t
) );
839 * Set the transmit tail to the new stop command.
844 * Tap the DMA channel to wake it up
846 IODBDMAContinue( ioBaseEnetTxDMA
);
851 /*-------------------------------------------------------------------------
854 * This routine runs the receiver in polled-mode (yuk!) for the kernel
857 * The _receivePackets allocate mbufs and pass them up the stack. The kernel
858 * debugger interface passes a buffer into us. To reconcile the two interfaces,
859 * we allow the receive routine to continue to allocate its own buffers and
860 * transfer any received data to the passed-in buffer. This is handled by
861 * _receivePacket calling _packetToDebugger.
862 *-------------------------------------------------------------------------*/
864 void MaceEnet::_receivePacket(void *pkt
, unsigned int *pkt_len
,
865 unsigned int timeout
)
868 ns_time_t currentTime
;
869 u_int32_t elapsedTimeMS
;
871 if (!ready
|| !pkt
|| !pkt_len
)
879 _IOGetTimestamp(&startTime
);
882 _receivePackets(true);
883 _IOGetTimestamp(¤tTime
);
884 elapsedTimeMS
= (currentTime
- startTime
) / (1000*1000);
886 while ( (debuggerPktSize
== 0) && (elapsedTimeMS
< timeout
) );
888 *pkt_len
= debuggerPktSize
;
893 /*-------------------------------------------------------------------------
896 * This is called by _receivePackets when we are polling for kernel debugger
897 * packets. It copies the mbuf contents to the buffer passed by the debugger.
898 * It also sets the var debuggerPktSize which will break the polling loop.
899 *-------------------------------------------------------------------------*/
901 void MaceEnet::_packetToDebugger(struct mbuf
* packet
, u_int size
)
903 debuggerPktSize
= size
;
904 bcopy( mtod(packet
, char *), debuggerPkt
, size
);
907 /*-------------------------------------------------------------------------
911 * This routine runs the transmitter in polled-mode (yuk!) for the
914 *-------------------------------------------------------------------------*/
916 void MaceEnet::_sendPacket(void *pkt
, unsigned int pkt_len
)
919 ns_time_t currentTime
;
920 u_int32_t elapsedTimeMS
;
922 if ( !ready
|| !pkt
|| (pkt_len
> ETHERMAXPACKET
))
926 * Wait for the transmit ring to empty
928 _IOGetTimestamp(&startTime
);
931 _transmitInterruptOccurred(true);
932 _IOGetTimestamp(¤tTime
);
933 elapsedTimeMS
= (currentTime
- startTime
) / (1000*1000);
935 while ( (txCommandHead
!= txCommandTail
) &&
936 (elapsedTimeMS
< TX_KDB_TIMEOUT
) );
938 if ( txCommandHead
!= txCommandTail
)
940 IOLog( "Mace: Polled tranmit timeout - 1\n\r");
944 txDebuggerPkt
->m_next
= 0;
945 txDebuggerPkt
->m_data
= (caddr_t
) pkt
;
946 txDebuggerPkt
->m_pkthdr
.len
= txDebuggerPkt
->m_len
= pkt_len
;
949 * Send the debugger packet. txDebuggerPkt must not be freed by
950 * the transmit routine.
952 _transmitPacket(txDebuggerPkt
);
955 * Poll waiting for the transmit ring to empty again
959 _transmitInterruptOccurred(true);
960 _IOGetTimestamp(¤tTime
);
961 elapsedTimeMS
= (currentTime
- startTime
) / (1000*1000);
963 while ( (txCommandHead
!= txCommandTail
) &&
964 (elapsedTimeMS
< TX_KDB_TIMEOUT
) );
966 if ( txCommandHead
!= txCommandTail
)
968 IOLog("Mace: Polled transmit timeout - 2\n\r");
974 /*-------------------------------------------------------------------------
978 *-------------------------------------------------------------------------*/
980 bool MaceEnet::_receiveInterruptOccurred()
982 return _receivePackets(false);
985 /*-------------------------------------------------------------------------
989 *-------------------------------------------------------------------------*/
991 bool MaceEnet::_receivePackets(bool fDebugger
)
993 enet_dma_cmd_t tmpCommand
;
994 struct mbuf
* packet
;
996 u_int32_t dmaChnlStatus
;
997 int receivedFrameSize
= 0;
998 u_int32_t dmaCount
[2], dmaResid
[2], dmaStatus
[2];
1001 bool useNetif
= !fDebugger
&& netifClient
;
1002 bool packetsQueued
= false;
1003 u_int8_t
*rxFS
= NULL
;
1005 static const u_int32_t lastResetValue
= (u_int32_t
)(-1);
1007 last
= lastResetValue
;
1015 * Purge cache references for the DBDMA entry we are about to look at.
1017 invalidate_cache_v((vm_offset_t
)&rxDMACommands
[i
],
1018 sizeof(enet_dma_cmd_t
));
1021 * Collect the DMA residual counts/status for the two buffer segments.
1023 for ( j
= 0; j
< 2; j
++ )
1025 dmaResid
[j
] = IOGetCCResult( &rxDMACommands
[i
].desc_seg
[j
] );
1026 dmaStatus
[j
] = dmaResid
[j
] >> 16;
1027 dmaResid
[j
] &= 0x0000ffff;
1028 dmaCount
[j
] = IOGetCCOperation( &rxDMACommands
[i
].desc_seg
[j
] ) &
1033 IOLog("Ethernet(Mace): Rx NetBuf[%2d] = %08x Resid[0] = %04x Status[0] = %04x Resid[1] = %04x Status[1] = %04x\n\r",
1034 i
, (int)nb_map(rxNetbuf
[i
]), dmaResid
[0], dmaStatus
[0], dmaResid
[1], dmaStatus
[1] );
1038 * If the current entry has not been written, then stop at this entry
1040 if ( !((dmaStatus
[0] & kdbdmaBt
) || (dmaStatus
[1] & kdbdmaActive
)) )
1046 * The Mace Ethernet controller appends four bytes to each receive
1047 * buffer containing the buffer size and receive frame status.
1048 * We locate these bytes by using the DMA residual counts.
1050 receivedFrameSize
= dmaCount
[0] - dmaResid
[0] + dmaCount
[1] -
1051 ((dmaStatus
[0] & kdbdmaBt
) ? dmaCount
[1] : dmaResid
[1]);
1053 if ( ( receivedFrameSize
>= 4 ) &&
1054 ( receivedFrameSize
<= NETWORK_BUFSIZE
) )
1057 * Get the receive frame size as reported by the Mace controller
1060 rxFS
= mtod(rxMbuf
[i
], u_int8_t
*) + receivedFrameSize
- 4;
1062 receivedFrameSize
= (u_int16_t
) rxFS
[0] |
1063 (rxFS
[1] & kRcvFS1RcvCnt
) << 8;
1067 * Reject packets that are runts or that have other mutations.
1069 if ( receivedFrameSize
< (ETHERMINPACKET
- ETHERCRC
) ||
1070 receivedFrameSize
> (ETHERMAXPACKET
+ ETHERCRC
) ||
1071 (rxFS
[1] & (kRcvFS1OFlo
| kRcvFS1Clsn
| kRcvFS1Fram
| kRcvFS1FCS
))
1074 if (useNetif
) netStats
->inputErrors
++;
1077 else if ( useNetif
== false )
1080 * Always reuse packets in debugger mode.
1084 _packetToDebugger(rxMbuf
[i
], receivedFrameSize
);
1088 * Before we pass this packet up the networking stack. Make sure we
1089 * can get a replacement. Otherwise, hold on to the current packet and
1090 * increment the input error count.
1096 if ( reusePkt
== false )
1100 packet
= replaceOrCopyPacket(&rxMbuf
[i
], receivedFrameSize
,
1105 if (packet
&& replaced
)
1107 status
= _updateDescriptorFromMbuf(rxMbuf
[i
],
1108 &rxDMACommands
[i
], true);
1116 // Assume descriptor has not been corrupted.
1117 freePacket(rxMbuf
[i
]); // release new packet.
1118 rxMbuf
[i
] = packet
; // get the old packet back.
1119 packet
= 0; // pass up nothing.
1120 IOLog("Mace: _updateDescriptorFromMbuf error\n");
1125 netStats
->inputErrors
++;
1129 * If we are reusing the existing mbuf, then refurbish the existing
1130 * DMA command \ descriptors by clearing the status/residual count
1134 if ( reusePkt
== true )
1136 for ( j
=0; j
< sizeof(enet_dma_cmd_t
)/sizeof(IODBDMADescriptor
);
1139 IOSetCCResult( &rxDMACommands
[i
].desc_seg
[j
], 0 );
1141 flush_cache_v( (vm_offset_t
)&rxDMACommands
[i
],
1142 sizeof(enet_dma_cmd_t
) );
1146 * Keep track of the last receive descriptor processed
1151 * Implement ring wrap-around
1153 if (++i
>= rxMaxCommand
) i
= 0;
1156 * Early exit in debugger mode.
1164 * Transfer received to network stack.
1168 KERNEL_DEBUG(DBG_MACE_RXCOMPLETE
| DBG_FUNC_NONE
, (int) packet
,
1169 (int)receivedFrameSize
, 0, 0, 0 );
1172 * The KDB lock must be held before calling this function.
1174 networkInterface
->inputPacket(packet
, receivedFrameSize
, true);
1175 netStats
->inputPackets
++;
1176 packetsQueued
= true;
1181 * OK...this is a little messy
1183 * We just processed a bunch of DMA receive descriptors. We are going to
1184 * exchange the current DMA stop command (rxCommandTail) with the last
1185 * receive descriptor we processed (last). This will make these list of
1186 * descriptors we just processed available. If we processed no receive
1187 * descriptors on this call then skip this exchange.
1191 IOLog("Mace: Prev - Rx Head = %2d Rx Tail = %2d Rx Last = %2d\n\r",
1192 rxCommandHead
, rxCommandTail
, last
);
1195 if ( last
!= lastResetValue
)
1198 * Save the contents of the last receive descriptor processed.
1200 packet
= rxMbuf
[last
];
1201 tmpCommand
= rxDMACommands
[last
];
1204 * Write a DMA stop command into this descriptor slot
1206 rxDMACommands
[last
].desc_seg
[0] = dbdmaCmd_Stop
;
1207 rxDMACommands
[last
].desc_seg
[1] = dbdmaCmd_Nop
;
1210 flush_cache_v( (vm_offset_t
)&rxDMACommands
[last
],
1211 sizeof(enet_dma_cmd_t
) );
1214 * Replace the previous DMA stop command with the last receive
1215 * descriptor processed.
1217 * The new DMA command is written into the channel program so that the
1218 * command word for the old Stop command is overwritten last. This
1219 * prevents the DMA engine from executing a partially written channel
1222 * Note: When relocating the descriptor, we must update its branch
1223 * field to reflect its new location.
1225 nextDesc
= rxDMACommandsPhys
+ (int)&rxDMACommands
[rxCommandTail
+1] -
1227 IOSetCCCmdDep( &tmpCommand
.desc_seg
[0], nextDesc
);
1229 bcopy( (u_int32_t
*)&tmpCommand
+1,
1230 (u_int32_t
*)&rxDMACommands
[rxCommandTail
]+1,
1231 sizeof(enet_dma_cmd_t
)-sizeof(u_int32_t
) );
1233 flush_cache_v( (vm_offset_t
)&rxDMACommands
[rxCommandTail
],
1234 sizeof(enet_dma_cmd_t
) );
1236 rxMbuf
[rxCommandTail
] = packet
;
1238 rxDMACommands
[rxCommandTail
].desc_seg
[0].operation
=
1239 tmpCommand
.desc_seg
[0].operation
;
1241 flush_cache_v( (vm_offset_t
)&rxDMACommands
[rxCommandTail
],
1242 sizeof(IODBDMADescriptor
) );
1245 * Update rxCommmandTail to point to the new Stop command. Update
1246 * rxCommandHead to point to the next slot in the ring past the Stop
1249 rxCommandTail
= last
;
1254 * The DMA channel has a nasty habit of shutting down when there is a
1255 * non-recoverable error on receive. We get no interrupt for this since
1256 * the channel shuts down before the descriptor that causes the host
1257 * interrupt is executed.
1259 * We check if the channel is DEAD by checking the channel status reg.
1260 * Also, the watchdog timer can force receiver interrupt servicing based
1261 * on detecting that the receive DMA is DEAD.
1263 dmaChnlStatus
= IOGetDBDMAChannelStatus( ioBaseEnetRxDMA
);
1264 if ( dmaChnlStatus
& kdbdmaDead
)
1269 if (useNetif
) netStats
->inputErrors
++;
1270 IOLog( "Mace: Rx DMA Error - Status = %04x\n", dmaChnlStatus
);
1273 * Reset and reinitialize chip
1275 _restartChip(); // This must not block in debugger mode.
1280 * Tap the DMA to wake it up
1282 IODBDMAContinue( ioBaseEnetRxDMA
);
1286 IOLog( "Mace: New - Rx Head = %2d Rx Tail = %2d\n\r",
1287 rxCommandHead
, rxCommandTail
);
1290 return packetsQueued
;
1293 /*-------------------------------------------------------------------------
1297 *-------------------------------------------------------------------------*/
1299 bool MaceEnet::_transmitInterruptOccurred(bool fDebugger
= false)
1301 u_int32_t dmaStatus
;
1303 bool fServiced
= false;
1304 bool useNetif
= !fDebugger
&& netifClient
;
1306 // Set the debugTxPoll flag to indicate the debugger was active
1307 // and some cleanup may be needed when the driver returns to
1308 // normal operation.
1316 * Purge cache references for the DBDMA entry we are about to look at.
1318 invalidate_cache_v((vm_offset_t
)&txDMACommands
[txCommandHead
],
1319 sizeof(enet_txdma_cmd_t
));
1322 * Check the status of the last descriptor in this entry to see if
1323 * the DMA engine completed this entry.
1325 dmaStatus
= IOGetCCResult(
1326 &txDMACommands
[txCommandHead
].desc_seg
[3] ) >> 16;
1328 if ( !(dmaStatus
& kdbdmaActive
) )
1336 * Reset the status word for the entry we are about to process
1338 IOSetCCResult( &txDMACommands
[txCommandHead
].desc_seg
[3], 0 );
1340 flush_cache_v( (vm_offset_t
) &txDMACommands
[txCommandHead
].desc_seg
[3],
1341 sizeof(IODBDMADescriptor
) );
1344 * This DMA descriptor read the transmit frame status. See what it has
1347 xmtFS
= IOGetCCCmdDep( &txDMACommands
[txCommandHead
].desc_seg
[2] );
1348 if ( useNetif
&& (xmtFS
& kXmtFSXmtSV
) )
1350 if (xmtFS
& (kXmtFSUFlo
| kXmtFSLCol
| kXmtFSRtry
| kXmtFSLCar
) )
1352 netStats
->outputErrors
++;
1356 netStats
->outputPackets
++;
1359 if (xmtFS
& (kXmtFSOne
| kXmtFSMore
) )
1361 netStats
->collisions
++;
1366 * Free the mbuf we just transmitted.
1368 KERNEL_DEBUG(DBG_MACE_TXCOMPLETE
| DBG_FUNC_NONE
,
1369 (int) txMbuf
[txCommandHead
],
1370 (int) txMbuf
[txCommandHead
]->m_pkthdr
.len
, 0, 0, 0 );
1372 if (txMbuf
[txCommandHead
] != txDebuggerPkt
)
1377 // While in debugger mode, do not touch the mbuf pool.
1378 // Queue any used mbufs to a local queue. This queue
1379 // will get flushed after we exit from debugger mode.
1381 // During continuous debugger transmission and
1382 // interrupt polling, we expect only the txDebuggerPkt
1383 // to show up on the transmit mbuf ring.
1385 debugQueue
->enqueue( txMbuf
[txCommandHead
] );
1389 freePacket( txMbuf
[txCommandHead
] );
1393 txMbuf
[txCommandHead
] = 0;
1395 if ( ++txCommandHead
>= txMaxCommand
) txCommandHead
= 0;
1399 * The DMA channel has a nasty habit of shutting down when there is
1400 * non-recoverable error on transmit. We get no interrupt for this since
1401 * the channel shuts down before the descriptor that causes the host
1402 * interrupt is executed.
1404 * We check if the channel is DEAD by checking the channel status reg.
1405 * Also, the watchdog timer can force a transmitter reset if it sees no
1406 * interrupt activity for to consecutive timeout intervals.
1409 dmaStatus
= IOGetDBDMAChannelStatus( ioBaseEnetTxDMA
);
1410 if ( (dmaStatus
& kdbdmaDead
) || (txWDForceReset
== true) )
1413 * Read the transmit frame status and log error
1415 xmtFS
= ReadMaceRegister( ioBaseEnet
, kXmtFS
);
1416 if (useNetif
) netStats
->outputErrors
++;
1417 IOLog( "Mace: Tx DMA Error - Status = %04x FS = %02x\n\r",
1421 * Reset and reinitialize chip
1425 txWDForceReset
= false;
1432 /*-------------------------------------------------------------------------
1436 *-------------------------------------------------------------------------*/
1439 * Breaks up an ethernet data buffer into two physical chunks. We know that
1440 * the buffer can't straddle more than two pages. If the content of paddr2 is
1441 * zero this means that all of the buffer lies in one physical page. Note
1442 * that we use the fact that tx and rx descriptors have the same size and
1443 * same layout of relevent fields (data address and count).
1446 MaceEnet::_updateDescriptorFromMbuf(struct mbuf
* m
, enet_dma_cmd_t
*desc
,
1449 u_int32_t nextDesc
= 0;
1451 struct IOPhysicalSegment segVector
[2];
1454 * Although coalescing is always enabled, it cannot occur
1455 * while the driver is in debugger mode.
1457 segments
= mbufCursor
->getPhysicalSegmentsWithCoalesce(m
, segVector
);
1459 if ((!segments
) || (segments
> 2)) {
1460 IOLog("Mace: _updateDescriptorFromMbuf error, %d segments\n",
1465 if ( segments
== 1 )
1467 IOMakeDBDMADescriptor( (&desc
->desc_seg
[0]),
1468 ((isReceive
) ? kdbdmaInputLast
: kdbdmaOutputLast
),
1471 (kdbdmaBranchNever
),
1472 ((isReceive
) ? kdbdmaWaitNever
:
1474 (segVector
[0].length
),
1475 (segVector
[0].location
) );
1477 desc
->desc_seg
[1] = (isReceive
) ? dbdmaCmd_NopWInt
: dbdmaCmd_Nop
;
1483 nextDesc
= rxDMACommandsPhys
+ (int)desc
- (int)rxDMACommands
+
1484 sizeof(enet_dma_cmd_t
);
1487 IOMakeDBDMADescriptorDep( (&desc
->desc_seg
[0]),
1488 ((isReceive
) ? kdbdmaInputMore
: kdbdmaOutputMore
),
1490 ((isReceive
) ? kdbdmaIntIfTrue
: kdbdmaIntNever
),
1491 ((isReceive
) ? kdbdmaBranchIfTrue
:
1494 (segVector
[0].length
),
1495 (segVector
[0].location
),
1498 IOMakeDBDMADescriptor( (&desc
->desc_seg
[1]),
1499 ((isReceive
) ? kdbdmaInputLast
: kdbdmaOutputLast
),
1501 ((isReceive
) ? kdbdmaIntAlways
: kdbdmaIntNever
),
1502 (kdbdmaBranchNever
),
1503 ((isReceive
) ? kdbdmaWaitNever
:
1505 (segVector
[1].length
),
1506 (segVector
[1].location
) );
1509 flush_cache_v( (vm_offset_t
)desc
, sizeof(enet_dma_cmd_t
) );
1517 * Useful for testing.
1520 void MaceEnet::_dumpDesc(void * addr
, u_int32_t size
)
1526 _IOPhysicalFromVirtual( (vm_offset_t
) addr
, (vm_offset_t
*)&paddr
);
1528 p
= (unsigned long *)addr
;
1530 for ( i
=0; i
< size
/sizeof(IODBDMADescriptor
); i
++, p
+=4,
1531 paddr
+=sizeof(IODBDMADescriptor
) )
1533 IOLog("Ethernet(Mace): %08x(v) %08x(p): %08x %08x %08x %08x\n",
1536 (int)OSReadSwapInt32(p
, 0), (int)OSReadSwapInt32(p
, 4),
1537 (int)OSReadSwapInt32(p
, 8), (int)OSReadSwapInt32(p
, 12) );
1542 void MaceEnet::_dumpRegisters()
1546 IOLog("\nEthernet(Mace): IO Address = %08x", (int)ioBaseEnet
);
1548 dataValue
= ReadMaceRegister(ioBaseEnet
, kXmtFC
);
1549 IOLog("\nEthernet(Mace): Read Register %04x Transmit Frame Control = %02x", kXmtFC
, dataValue
);
1551 dataValue
= ReadMaceRegister(ioBaseEnet
, kXmtFS
);
1552 IOLog("\nEthernet(Mace): Read Register %04x Transmit Frame Status = %02x", kXmtFS
, dataValue
);
1554 dataValue
= ReadMaceRegister(ioBaseEnet
, kXmtRC
);
1555 IOLog("\nEthernet(Mace): Read Register %04x Transmit Retry Count = %02x", kXmtRC
, dataValue
);
1557 dataValue
= ReadMaceRegister(ioBaseEnet
, kRcvFC
);
1558 IOLog("\nEthernet(Mace): Read Register %04x Receive Frame Control = %02x", kRcvFC
, dataValue
);
1560 dataValue
= ReadMaceRegister(ioBaseEnet
, kRcvFS0
);
1561 IOLog("\nEthernet(Mace): Read Register %04x Receive Frame Status 0 = %02x", kRcvFS0
, dataValue
);
1562 dataValue
= ReadMaceRegister(ioBaseEnet
, kRcvFS1
);
1563 IOLog("\nEthernet(Mace): Read Register %04x Receive Frame Status 1 = %02x", kRcvFS1
, dataValue
);
1564 dataValue
= ReadMaceRegister(ioBaseEnet
, kRcvFS2
);
1565 IOLog("\nEthernet(Mace): Read Register %04x Receive Frame Status 2 = %02x", kRcvFS2
, dataValue
);
1566 dataValue
= ReadMaceRegister(ioBaseEnet
, kRcvFS3
);
1567 IOLog("\nEthernet(Mace): Read Register %04x Receive Frame Status 3 = %02x", kRcvFS3
, dataValue
);
1569 dataValue
= ReadMaceRegister(ioBaseEnet
, kFifoFC
);
1570 IOLog("\nEthernet(Mace): Read Register %04x FIFO Frame Count = %02x", kFifoFC
, dataValue
);
1572 dataValue
= ReadMaceRegister(ioBaseEnet
, kIntReg
);
1573 IOLog("\nEthernet(Mace): Read Register %04x Interrupt Register = %02x", kIntReg
, dataValue
);
1575 dataValue
= ReadMaceRegister(ioBaseEnet
, kIntMask
);
1576 IOLog("\nEthernet(Mace): Read Register %04x Interrupt Mask Register = %02x", kIntMask
, dataValue
);
1578 dataValue
= ReadMaceRegister(ioBaseEnet
, kPollReg
);
1579 IOLog("\nEthernet(Mace): Read Register %04x Poll Register = %02x", kPollReg
, dataValue
);
1581 dataValue
= ReadMaceRegister(ioBaseEnet
, kBIUCC
);
1582 IOLog("\nEthernet(Mace): Read Register %04x BUI Configuration Control = %02x", kBIUCC
, dataValue
);
1584 dataValue
= ReadMaceRegister(ioBaseEnet
, kFifoCC
);
1585 IOLog("\nEthernet(Mace): Read Register %04x FIFO Configuration Control = %02x", kFifoCC
, dataValue
);
1587 dataValue
= ReadMaceRegister(ioBaseEnet
, kMacCC
);
1588 IOLog("\nEthernet(Mace): Read Register %04x MAC Configuration Control = %02x", kMacCC
, dataValue
);
1590 dataValue
= ReadMaceRegister(ioBaseEnet
, kPLSCC
);
1591 IOLog("\nEthernet(Mace): Read Register %04x PLS Configuration Contro = %02x", kPLSCC
, dataValue
);
1593 dataValue
= ReadMaceRegister(ioBaseEnet
, kPHYCC
);
1594 IOLog("\nEthernet(Mace): Read Register %04x PHY Configuration Control = %02x", kPHYCC
, dataValue
);
1596 dataValue
= ReadMaceRegister(ioBaseEnet
, kMaceChipId0
);
1597 IOLog("\nEthernet(Mace): Read Register %04x MACE ChipID Register 7:0 = %02x", kMaceChipId0
, dataValue
);
1599 dataValue
= ReadMaceRegister(ioBaseEnet
, kMaceChipId1
);
1600 IOLog("\nEthernet(Mace): Read Register %04x MACE ChipID Register 15:8 = %02x", kMaceChipId1
, dataValue
);
1602 dataValue
= ReadMaceRegister(ioBaseEnet
, kMPC
);
1603 IOLog("\nEthernet(Mace): Read Register %04x Missed Packet Count = %02x", kMPC
, dataValue
);
1605 dataValue
= ReadMaceRegister(ioBaseEnet
, kUTR
);
1606 IOLog("\nEthernet(Mace): Read Register %04x User Test Register = %02x", kUTR
, dataValue
);
1607 IOLog("\nEthernet(Mace): -------------------------------------------------------\n" );
1612 /*-------------------------------------------------------------------------
1616 *-------------------------------------------------------------------------*/
1618 IOReturn
MaceEnet::getHardwareAddress(IOEthernetAddress
*ea
)
1622 for (UInt i
= 0; i
< sizeof(*ea
); i
++)
1624 data
= ((unsigned char *)ioBaseEnetROM
)[i
<< 4];
1625 ea
->bytes
[i
] = reverseBitOrder(data
);
1628 return kIOReturnSuccess
;
1631 /*-------------------------------------------------------------------------
1635 *-------------------------------------------------------------------------*/
1637 #define ENET_CRCPOLY 0x04c11db7
1639 /* Real fast bit-reversal algorithm, 6-bit values */
1640 static int reverse6
[] =
1641 { 0x0,0x20,0x10,0x30,0x8,0x28,0x18,0x38,
1642 0x4,0x24,0x14,0x34,0xc,0x2c,0x1c,0x3c,
1643 0x2,0x22,0x12,0x32,0xa,0x2a,0x1a,0x3a,
1644 0x6,0x26,0x16,0x36,0xe,0x2e,0x1e,0x3e,
1645 0x1,0x21,0x11,0x31,0x9,0x29,0x19,0x39,
1646 0x5,0x25,0x15,0x35,0xd,0x2d,0x1d,0x3d,
1647 0x3,0x23,0x13,0x33,0xb,0x2b,0x1b,0x3b,
1648 0x7,0x27,0x17,0x37,0xf,0x2f,0x1f,0x3f
1651 static u_int32_t
crc416(unsigned int current
, unsigned short nxtval
)
1653 register unsigned int counter
;
1654 register int highCRCBitSet
, lowDataBitSet
;
1657 nxtval
= ((nxtval
& 0x00FF) << 8) | (nxtval
>> 8);
1659 /* Compute bit-by-bit */
1660 for (counter
= 0; counter
!= 16; ++counter
)
1661 { /* is high CRC bit set? */
1662 if ((current
& 0x80000000) == 0)
1667 current
= current
<< 1;
1669 if ((nxtval
& 0x0001) == 0)
1674 nxtval
= nxtval
>> 1;
1677 if (highCRCBitSet
^ lowDataBitSet
)
1678 current
= current
^ ENET_CRCPOLY
;
1683 /*-------------------------------------------------------------------------
1687 *-------------------------------------------------------------------------*/
1689 static u_int32_t
mace_crc(unsigned short *address
)
1691 register u_int32_t newcrc
;
1693 newcrc
= crc416(0xffffffff, *address
); /* address bits 47 - 32 */
1694 newcrc
= crc416(newcrc
, address
[1]); /* address bits 31 - 16 */
1695 newcrc
= crc416(newcrc
, address
[2]); /* address bits 15 - 0 */
1701 * Clear the hash table filter.
1704 void MaceEnet::_resetHashTableMask()
1706 bzero(hashTableUseCount
, sizeof(hashTableUseCount
));
1707 bzero(hashTableMask
, sizeof(hashTableMask
));
1711 * Add requested mcast addr to Mace's hash table filter.
1714 void MaceEnet::_addToHashTableMask(u_int8_t
*addr
)
1719 crc
= mace_crc((unsigned short *)addr
)&0x3f; /* Big-endian alert! */
1720 crc
= reverse6
[crc
]; /* Hyperfast bit-reversing algorithm */
1721 if (hashTableUseCount
[crc
]++)
1722 return; /* This bit is already set */
1724 mask
= (unsigned char) 1 << mask
;
1725 hashTableMask
[crc
/8] |= mask
;
1728 /*-------------------------------------------------------------------------
1732 *-------------------------------------------------------------------------*/
1734 void MaceEnet::_removeFromHashTableMask(u_int8_t
*addr
)
1739 /* Now, delete the address from the filter copy, as indicated */
1740 crc
= mace_crc((unsigned short *)addr
)&0x3f; /* Big-endian alert! */
1741 crc
= reverse6
[crc
]; /* Hyperfast bit-reversing algorithm */
1742 if (hashTableUseCount
[crc
] == 0)
1743 return; /* That bit wasn't in use! */
1745 if (--hashTableUseCount
[crc
])
1746 return; /* That bit is still in use */
1749 mask
= ((unsigned char)1 << mask
) ^ 0xffff; /* To turn off bit */
1750 hashTableMask
[crc
/8] &= mask
;
1754 * Sync the adapter with the software copy of the multicast mask
1755 * (logical address filter).
1757 void MaceEnet::_updateHashTableMask()
1764 // Stop the receiver before changing the filter.
1766 MacCCReg
= ReadMaceRegister( ioBaseEnet
, kMacCC
);
1767 WriteMaceRegister( ioBaseEnet
, kMacCC
, MacCCReg
& ~kMacCCEnRcv
);
1768 IODelay( RECEIVE_QUIESCE_uS
);
1770 if ( chipId
!= kMaceRevisionA2
)
1772 WriteMaceRegister( ioBaseEnet
, kIAC
, kIACAddrChg
| kIACLogAddr
);
1775 status
= ReadMaceRegister( ioBaseEnet
, kIAC
);
1777 while( status
& kIACAddrChg
);
1781 WriteMaceRegister( ioBaseEnet
, kIAC
, kIACLogAddr
);
1784 p
= (u_int8_t
*) hashTableMask
;
1785 for (i
= 0; i
< 8; i
++, p
++ )
1787 WriteMaceRegister( ioBaseEnet
, kLADRF
, *p
);
1790 // Restore the engine's state.
1792 WriteMaceRegister( ioBaseEnet
, kMacCC
, MacCCReg
);