|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
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.
11: *
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
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1995-1996 NeXT Software, Inc.
24: *
25: * Implementation for hardware dependent (relatively) code
26: * for the Mace Ethernet controller.
27: *
28: * HISTORY
29: *
30: * 10-Sept-97
31: * Created.
32: *
33: */
34:
35: #include <IOKit/assert.h>
36: #include <IOKit/system.h>
37: #include <IOKit/IOLib.h>
38: #include "MaceEnetPrivate.h"
39:
40:
41: /*****************************************************************************
42: *
43: * Hacks.
44: */
45:
46: typedef unsigned long long ns_time_t; /* nanoseconds! */
47:
48: #define NSEC_PER_SEC 1000000000
49:
50: static void
51: _IOGetTimestamp(ns_time_t *nsp)
52: {
53: mach_timespec_t now;
54:
55: IOGetTime(&now);
56: *nsp = ((ns_time_t)now.tv_sec * NSEC_PER_SEC) + now.tv_nsec;
57: }
58:
59: /*
60: * Find a physical address (if any) for the specified virtual address.
61: *
62: * Note: what about vm_offset_t kvtophys(vm_offset_t va)
63: */
64: static IOReturn _IOPhysicalFromVirtual(
65: vm_address_t virtualAddress,
66: unsigned *physicalAddress)
67: {
68: *physicalAddress = pmap_extract(kernel_pmap, virtualAddress);
69: if(*physicalAddress == 0) {
70: return kIOReturnBadArgument;
71: }
72: else {
73: return kIOReturnSuccess;
74: }
75: }
76:
77: // From osfmk/ppc/pmap.h
78: //
79: extern "C" {
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);
82: }
83:
84: static inline void
85: invalidate_cache_v(vm_offset_t va, unsigned length)
86: {
87: invalidate_dcache(va, length, 0);
88: }
89:
90: static inline void
91: flush_cache_v(vm_offset_t va, unsigned length)
92: {
93: flush_dcache(va, length, 0);
94: }
95:
96: /****************************************************************************/
97:
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;
104:
105:
106: static u_int8_t reverseBitOrder(u_int8_t data )
107: {
108: u_int8_t val = 0;
109: int i;
110:
111: for ( i=0; i < 8; i++ )
112: {
113: val <<= 1;
114: if (data & 1) val |= 1;
115: data >>= 1;
116: }
117: return( val );
118: }
119:
120: /*
121: * Function: IOMallocPage
122: *
123: * Purpose:
124: * Returns a pointer to a page-aligned memory block of size >= PAGE_SIZE
125: *
126: * Return:
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);
129: */
130: static void *
131: IOMallocPage(int request_size, void ** actual_ptr, u_int * actual_size)
132: {
133: void * mem_ptr;
134:
135: *actual_size = round_page(request_size) + PAGE_SIZE;
136: mem_ptr = IOMalloc(*actual_size);
137: if (mem_ptr == NULL)
138: return NULL;
139: *actual_ptr = mem_ptr;
140: return ((void *)round_page(mem_ptr));
141: }
142:
143: /*
144: * Private functions
145: */
146: bool MaceEnet::_allocateMemory()
147: {
148: u_int32_t i, n;
149: unsigned char * virtAddr;
150: u_int32_t physBase;
151: u_int32_t physAddr;
152: u_int32_t dbdmaSize;
153:
154: /*
155: * Calculate total space for DMA channel commands
156: */
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) );
161:
162: /*
163: * Allocate required memory
164: */
165: dmaMemory.size = dbdmaSize;
166: dmaMemory.ptr = (void *)IOMallocPage(
167: dmaMemory.size,
168: &dmaMemory.ptrReal,
169: &dmaMemory.sizeReal
170: );
171:
172: dmaCommands = (unsigned char *) dmaMemory.ptr;
173: if (!dmaCommands) {
174: IOLog( "Mace: Cant allocate channel DBDMA commands\n\r" );
175: return false;
176: }
177:
178: /*
179: * If we needed more than one page, then make sure we received
180: * contiguous memory.
181: */
182: n = (dbdmaSize - PAGE_SIZE) / PAGE_SIZE;
183: _IOPhysicalFromVirtual((vm_address_t) dmaCommands, &physBase );
184:
185: virtAddr = (unsigned char *) dmaCommands;
186: for( i=0; i < n; i++, virtAddr += PAGE_SIZE )
187: {
188: _IOPhysicalFromVirtual( (vm_address_t) virtAddr, &physAddr );
189: if (physAddr != (physBase + i * PAGE_SIZE) )
190: {
191: IOLog("Mace: Cannot allocate contiguous memory for DBDMA "
192: "commands\n");
193: return false;
194: }
195: }
196:
197: /*
198: * Setup the receive ring pointers
199: */
200: rxDMACommands = (enet_dma_cmd_t *)dmaCommands;
201: rxMaxCommand = RX_RING_LENGTH;
202:
203: /*
204: * Setup the transmit ring pointers
205: */
206: txDMACommands = (enet_txdma_cmd_t *)(
207: dmaCommands +
208: RX_RING_LENGTH * sizeof(enet_dma_cmd_t) +
209: sizeof(IODBDMADescriptor));
210:
211: txMaxCommand = TX_RING_LENGTH;
212:
213: /*
214: * Setup pre-initialized DBDMA commands
215: */
216: IOMakeDBDMADescriptor( (&dbdmaCmd_Nop),
217: kdbdmaNop,
218: kdbdmaKeyStream0,
219: kdbdmaIntNever,
220: kdbdmaBranchNever,
221: kdbdmaWaitNever,
222: 0,
223: 0 );
224:
225: IOMakeDBDMADescriptor( (&dbdmaCmd_NopWInt),
226: kdbdmaNop,
227: kdbdmaKeyStream0,
228: kdbdmaIntAlways,
229: kdbdmaBranchNever,
230: kdbdmaWaitNever,
231: 0,
232: 0 );
233:
234: UInt32 ioBaseEnetPhys = maps[MEMORY_MAP_ENET_INDEX]->getPhysicalAddress();
235:
236: IOMakeDBDMADescriptor( (&dbdmaCmd_LoadXFS),
237: kdbdmaLoadQuad,
238: kdbdmaKeySystem,
239: kdbdmaIntNever,
240: kdbdmaBranchNever,
241: kdbdmaWaitNever,
242: 1,
243: ((int)ioBaseEnetPhys + kXmtFS) );
244:
245: IOMakeDBDMADescriptor( (&dbdmaCmd_LoadIntwInt),
246: kdbdmaLoadQuad,
247: kdbdmaKeySystem,
248: kdbdmaIntAlways,
249: kdbdmaBranchNever,
250: kdbdmaWaitNever,
251: 1,
252: ((int)ioBaseEnetPhys + kIntReg) );
253:
254: IOMakeDBDMADescriptor( (&dbdmaCmd_Stop),
255: kdbdmaStop,
256: kdbdmaKeyStream0,
257: kdbdmaIntNever,
258: kdbdmaBranchNever,
259: kdbdmaWaitNever,
260: 0,
261: 0 );
262:
263: IOMakeDBDMADescriptor( (&dbdmaCmd_Branch),
264: kdbdmaNop,
265: kdbdmaKeyStream0,
266: kdbdmaIntNever,
267: kdbdmaBranchAlways,
268: kdbdmaWaitNever,
269: 0,
270: 0 );
271:
272: return true;
273: }
274:
275: /*-------------------------------------------------------------------------
276: *
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
284: * first entry.
285: *-------------------------------------------------------------------------*/
286:
287: bool MaceEnet::_initTxRing()
288: {
289: bool kr;
290: u_int32_t i;
291:
292: /*
293: * Clear the transmit DMA command memory
294: */
295: bzero( (void *)txDMACommands, sizeof(enet_txdma_cmd_t) * txMaxCommand);
296: txCommandHead = 0;
297: txCommandTail = 0;
298:
299: /*
300: * DMA Channel commands 2,3 are the same for all DBDMA entries on transmit.
301: * Initialize them now.
302: */
303: for( i=0; i < txMaxCommand; i++ )
304: {
305: txDMACommands[i].desc_seg[2] = dbdmaCmd_LoadXFS;
306: txDMACommands[i].desc_seg[3] = dbdmaCmd_LoadIntwInt;
307: }
308:
309: /*
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
312: * transmit ring.
313: */
314: txDMACommands[txMaxCommand].desc_seg[0] = dbdmaCmd_Branch;
315:
316: kr = _IOPhysicalFromVirtual( (vm_address_t) txDMACommands,
317: (u_int32_t *)&txDMACommandsPhys );
318: if ( kr != kIOReturnSuccess )
319: {
320: IOLog("Mace: Bad Tx DBDMA command buf - %08x\n\r",
321: (u_int32_t)txDMACommands );
322: }
323: IOSetCCCmdDep( &txDMACommands[txMaxCommand].desc_seg[0],
324: txDMACommandsPhys );
325:
326: /*
327: * Set the Transmit DMA Channel pointer to the first entry in the
328: * transmit ring.
329: */
330: IOSetDBDMACommandPtr( ioBaseEnetTxDMA, txDMACommandsPhys );
331:
332: /*
333: * Push the DMA channel words into physical memory.
334: */
335: flush_cache_v( (vm_offset_t)txDMACommands,
336: txMaxCommand*sizeof(enet_txdma_cmd_t) + sizeof(IODBDMADescriptor));
337:
338: return true;
339: }
340:
341: /*-------------------------------------------------------------------------
342: *
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
349: * entry.
350: *
351: *-------------------------------------------------------------------------*/
352:
353: bool MaceEnet::_initRxRing()
354: {
355: u_int32_t i;
356: bool status;
357: IOReturn kr;
358:
359: /*
360: * Clear the receive DMA command memory
361: */
362: bzero( (void *)rxDMACommands, sizeof(enet_dma_cmd_t) * rxMaxCommand);
363:
364: kr = _IOPhysicalFromVirtual( (vm_address_t) rxDMACommands,
365: (u_int32_t *)&rxDMACommandsPhys );
366: if ( kr != kIOReturnSuccess )
367: {
368: IOLog("Mace: Bad Rx DBDMA command buf - %08x\n\r",
369: (u_int32_t)rxDMACommands );
370: return false;
371: }
372:
373: /*
374: * Allocate a receive buffer for each entry in the Receive ring
375: */
376: for (i = 0; i < rxMaxCommand-1; i++)
377: {
378: if (rxMbuf[i] == 0)
379: {
380: rxMbuf[i] = allocatePacket(NETWORK_BUFSIZE);
381:
382: if (!rxMbuf[i])
383: {
384: IOLog("Mace: allocatePacket failed in _initRxRing()\n\r");
385: return false;
386: }
387: }
388:
389: /*
390: * Set the DMA commands for the ring entry to transfer data to the
391: * mbuf.
392: */
393: status = _updateDescriptorFromMbuf(rxMbuf[i], &rxDMACommands[i], true);
394: if (status == false)
395: {
396: IOLog("Mace: Cant map mbuf to physical memory in _initRxRing\n\r");
397: return false;
398: }
399: }
400:
401: /*
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
404: * last ring entry
405: */
406: rxCommandHead = 0;
407: rxCommandTail = i;
408:
409: rxDMACommands[i].desc_seg[0] = dbdmaCmd_Stop;
410: rxDMACommands[i].desc_seg[1] = dbdmaCmd_Nop;
411:
412: /*
413: * Setup a DMA branch command after the stop command
414: */
415: i++;
416: rxDMACommands[i].desc_seg[0] = dbdmaCmd_Branch;
417:
418: IOSetCCCmdDep( &rxDMACommands[i].desc_seg[0], rxDMACommandsPhys );
419:
420: /*
421: * Set DMA command pointer to first receive entry
422: */
423: IOSetDBDMACommandPtr( ioBaseEnetRxDMA, rxDMACommandsPhys );
424:
425: /*
426: * Push DMA commands to physical memory
427: */
428: flush_cache_v( (vm_offset_t)&rxDMACommands[rxCommandTail],
429: 2 * sizeof(enet_dma_cmd_t) );
430:
431: return true;
432: }
433:
434: /*-------------------------------------------------------------------------
435: *
436: *
437: *
438: *-------------------------------------------------------------------------*/
439:
440: void MaceEnet::_startChip()
441: {
442: WriteMaceRegister( ioBaseEnet, kMacCC, kMacCCEnXmt | kMacCCEnRcv );
443:
444: // enable rx dma channel
445: IODBDMAContinue( ioBaseEnetRxDMA );
446: }
447:
448: /*-------------------------------------------------------------------------
449: *
450: *
451: *
452: *-------------------------------------------------------------------------*/
453:
454: void MaceEnet::_resetChip()
455: {
456: u_int8_t regValue;
457:
458: /*
459: * Mace errata - chip reset does not clear pending interrupts
460: */
461: ReadMaceRegister( ioBaseEnet, kIntReg );
462:
463: IODBDMAReset( ioBaseEnetRxDMA );
464: IODBDMAReset( ioBaseEnetTxDMA );
465:
466: IOSetDBDMAWaitSelect( ioBaseEnetTxDMA,
467: IOSetDBDMAChannelControlBits( kdbdmaS5 ) );
468:
469: IOSetDBDMABranchSelect( ioBaseEnetRxDMA,
470: IOSetDBDMAChannelControlBits( kdbdmaS6 ) );
471:
472: IOSetDBDMAInterruptSelect( ioBaseEnetRxDMA,
473: IOSetDBDMAChannelControlBits( kdbdmaS6 ) );
474:
475: WriteMaceRegister( ioBaseEnet, kBIUCC, kBIUCCSWRst );
476: do
477: {
478: regValue = ReadMaceRegister( ioBaseEnet, kBIUCC );
479: }
480: while( regValue & kBIUCCSWRst );
481: }
482:
483: /*-------------------------------------------------------------------------
484: *
485: *
486: *
487: *-------------------------------------------------------------------------*/
488:
489: bool MaceEnet::_initChip()
490: {
491: volatile u_int16_t regValue;
492: u_int32_t i;
493:
494: _disableAdapterInterrupts();
495:
496: chipId = ReadMaceRegister( ioBaseEnet, kMaceChipId0 );
497: chipId |= ReadMaceRegister( ioBaseEnet, kMaceChipId1 ) << 8;
498:
499: /*
500: * Turn off ethernet header stripping
501: */
502: regValue = ReadMaceRegister( ioBaseEnet, kRcvFC );
503: regValue &= ~kRcvFCAStrpRcv;
504: WriteMaceRegister( ioBaseEnet, kRcvFC, regValue );
505:
506: /*
507: * Set Mace destination address.
508: */
509: if ( chipId != kMaceRevisionA2 )
510: {
511: WriteMaceRegister( ioBaseEnet, kIAC, kIACAddrChg | kIACPhyAddr );
512: do
513: {
514: regValue = ReadMaceRegister( ioBaseEnet, kIAC );
515: }
516: while( regValue & kIACAddrChg );
517: }
518: else
519: {
520: WriteMaceRegister( ioBaseEnet, kIAC, kIACPhyAddr );
521: }
522:
523: for (i=0; i < sizeof(enet_addr_t); i++ )
524: {
525: WriteMaceRegister( ioBaseEnet, kPADR,
526: reverseBitOrder(((unsigned char *)ioBaseEnetROM)[i<<4]) );
527: }
528:
529: /*
530: * Clear logical address (multicast) filter
531: */
532: if ( chipId != kMaceRevisionA2 )
533: {
534: WriteMaceRegister( ioBaseEnet, kIAC, kIACAddrChg | kIACLogAddr );
535: do
536: {
537: regValue = ReadMaceRegister( ioBaseEnet, kIAC );
538: }
539: while( regValue & kIACAddrChg );
540: }
541: else
542: {
543: WriteMaceRegister( ioBaseEnet, kIAC, kIACLogAddr );
544: }
545:
546: for (i = 0; i < 8; i++ )
547: {
548: WriteMaceRegister( ioBaseEnet, kLADRF, 0 );
549: }
550:
551: /*
552: * Enable ethernet transceiver
553: */
554: WriteMaceRegister( ioBaseEnet, kPLSCC, kPLSCCPortSelGPSI | kPLSCCEnSts );
555:
556: return true;
557: }
558:
559:
560: /*-------------------------------------------------------------------------
561: *
562: *
563: *
564: *-------------------------------------------------------------------------*/
565:
566: void MaceEnet::_restartChip()
567: {
568: /*
569: * Shutdown DMA channels
570: */
571: _stopReceiveDMA();
572: _stopTransmitDMA();
573:
574: /*
575: * Get the silicon's attention
576: */
577: _resetChip();
578: _initChip();
579:
580: /*
581: * Restore multicast settings
582: */
583: _updateHashTableMask();
584:
585: if ( isPromiscuous )
586: {
587: _setPromiscuousMode(kIOEnetPromiscuousModeOn);
588: }
589:
590: /*
591: * Enable receiver and transmitter
592: */
593: _startChip();
594: _enableAdapterInterrupts();
595:
596: /*
597: * Restart transmit DMA
598: */
599: IODBDMAContinue( ioBaseEnetTxDMA );
600: }
601:
602: /*-------------------------------------------------------------------------
603: *
604: * Orderly stop of receive DMA.
605: *
606: *
607: *-------------------------------------------------------------------------*/
608:
609: void MaceEnet::_stopReceiveDMA()
610: {
611: u_int32_t dmaStatus;
612: u_int32_t dmaCmdPtr;
613: u_int32_t dmaIndex;
614: u_int8_t tmpBuf[16];
615: u_int8_t *p = 0;
616: u_int8_t MacCCReg;
617:
618: /*
619: * Stop the receiver and allow any frame receive in progress to complete
620: */
621: MacCCReg = ReadMaceRegister( ioBaseEnet, kMacCC );
622: WriteMaceRegister( ioBaseEnet, kMacCC, MacCCReg & ~kMacCCEnRcv );
623: IODelay( RECEIVE_QUIESCE_uS );
624:
625: /*
626: * Capture channel status and pause the dma channel.
627: */
628: dmaStatus = IOGetDBDMAChannelStatus( ioBaseEnetRxDMA );
629: IODBDMAPause( ioBaseEnetRxDMA );
630:
631: /*
632: * Read the command pointer and convert it to a byte offset into the
633: * DMA program.
634: */
635: dmaCmdPtr = IOGetDBDMACommandPtr( ioBaseEnetRxDMA );
636: dmaIndex = (dmaCmdPtr - rxDMACommandsPhys);
637:
638: /*
639: * If the channel status is DEAD, the DMA pointer is pointing to the
640: * next command
641: */
642: if ( dmaStatus & kdbdmaDead )
643: {
644: dmaIndex -= sizeof(IODBDMADescriptor);
645: }
646:
647: /*
648: * Convert channel program offset to command index
649: */
650: dmaIndex = dmaIndex / sizeof(enet_dma_cmd_t);
651: if ( dmaIndex >= rxMaxCommand ) dmaIndex = 0;
652:
653: /*
654: * The DMA controller doesnt like being stopped before transferring any
655: * data.
656: *
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
660: * the channel.
661: *
662: */
663: if ( rxMbuf[dmaIndex] )
664: {
665: p = mtod(rxMbuf[dmaIndex], u_int8_t *);
666: }
667:
668: (u_int32_t)p &= ~0x0f;
669:
670: if ( p )
671: {
672: bcopy( p, tmpBuf, 16 );
673: }
674:
675: IODBDMAReset( ioBaseEnetRxDMA );
676:
677: if ( p )
678: {
679: bcopy( tmpBuf, p, 16 );
680: }
681:
682: /*
683: * Reset the dma channel pointer to the nearest command index
684: */
685: dmaCmdPtr = rxDMACommandsPhys + sizeof(enet_dma_cmd_t) * dmaIndex;
686: IOSetDBDMACommandPtr( ioBaseEnetRxDMA, dmaCmdPtr);
687: }
688:
689: /*-------------------------------------------------------------------------
690: *
691: *
692: *
693: *-------------------------------------------------------------------------*/
694:
695: void MaceEnet::_stopTransmitDMA()
696: {
697: u_int32_t dmaStatus;
698: u_int32_t dmaCmdPtr;
699: u_int32_t dmaIndex;
700: u_int8_t MacCCReg;
701:
702: /*
703: * Stop the transmitter and allow any frame transmit in progress to abort
704: */
705: MacCCReg = ReadMaceRegister( ioBaseEnet, kMacCC );
706: WriteMaceRegister( ioBaseEnet, kMacCC, MacCCReg & ~kMacCCEnXmt );
707: IODelay( TRANSMIT_QUIESCE_uS );
708:
709: /*
710: * Capture channel status and pause the dma channel.
711: */
712: dmaStatus = IOGetDBDMAChannelStatus( ioBaseEnetTxDMA );
713: IODBDMAPause( ioBaseEnetTxDMA );
714:
715: /*
716: * Read the command pointer and convert it to a byte offset into the
717: * DMA program.
718: */
719: dmaCmdPtr = IOGetDBDMACommandPtr( ioBaseEnetTxDMA );
720: dmaIndex = (dmaCmdPtr - txDMACommandsPhys);
721:
722: /*
723: * If the channel status is DEAD, the DMA pointer is pointing to the
724: * next command
725: */
726: if ( dmaStatus & kdbdmaDead )
727: {
728: dmaIndex -= sizeof(IODBDMADescriptor);
729: }
730:
731: /*
732: * Convert channel program offset to command index
733: */
734: dmaIndex = dmaIndex / sizeof(enet_txdma_cmd_t);
735: if ( dmaIndex >= txMaxCommand ) dmaIndex = 0;
736:
737: IODBDMAReset( ioBaseEnetTxDMA );
738:
739: /*
740: * Reset the dma channel pointer to the nearest command index
741: */
742: dmaCmdPtr = txDMACommandsPhys + sizeof(enet_txdma_cmd_t) * dmaIndex;
743: IOSetDBDMACommandPtr( ioBaseEnetTxDMA, dmaCmdPtr );
744: }
745:
746: /*-------------------------------------------------------------------------
747: *
748: *
749: *
750: *-------------------------------------------------------------------------*/
751:
752: void MaceEnet::_disableAdapterInterrupts()
753: {
754: WriteMaceRegister( ioBaseEnet, kIntMask, 0xFF );
755: }
756:
757: /*-------------------------------------------------------------------------
758: *
759: * _enableAdapterInterrupts
760: *
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.
765: *
766: *-------------------------------------------------------------------------*/
767:
768: void MaceEnet::_enableAdapterInterrupts()
769: {
770: u_int8_t regValue;
771:
772: regValue = ReadMaceRegister( ioBaseEnet, kIntMask );
773: regValue &= ~kIntMaskXmtInt;
774: WriteMaceRegister( ioBaseEnet, kIntMask, regValue );
775: IODelay(500);
776: ReadMaceRegister( ioBaseEnet, kXmtFS );
777: ReadMaceRegister( ioBaseEnet, kIntReg );
778: }
779:
780: /*-------------------------------------------------------------------------
781: *
782: *
783: *
784: *-------------------------------------------------------------------------*/
785:
786: bool MaceEnet::_transmitPacket(struct mbuf * packet)
787: {
788: enet_dma_cmd_t tmpCommand;
789: u_int32_t i;
790:
791: /*
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.
795: *
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.
800: */
801: i = txCommandTail + 1;
802: if ( i >= txMaxCommand ) i = 0;
803:
804: if ( (i == txCommandHead) ||
805: !_updateDescriptorFromMbuf(packet, &tmpCommand, false))
806: {
807: IOLog("Mace: Freeing transmit packet eh?\n\r");
808: if (packet != txDebuggerPkt)
809: freePacket(packet);
810: return false;
811: }
812:
813: /*
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.
818: */
819: txDMACommands[i].desc_seg[0] = dbdmaCmd_Stop;
820: txDMACommands[i].desc_seg[1] = dbdmaCmd_Nop;
821:
822: flush_cache_v( (vm_offset_t)&txDMACommands[i], sizeof(enet_dma_cmd_t) );
823:
824: bcopy( ((u_int32_t *)&tmpCommand)+1,
825: ((u_int32_t *)&txDMACommands[txCommandTail])+1,
826: sizeof(enet_dma_cmd_t)-sizeof(u_int32_t) );
827:
828: flush_cache_v( (vm_offset_t)&txDMACommands[txCommandTail],
829: sizeof(enet_dma_cmd_t) );
830:
831: txMbuf[txCommandTail] = packet;
832: txDMACommands[txCommandTail].desc_seg[0].operation =
833: tmpCommand.desc_seg[0].operation;
834:
835: flush_cache_v( (vm_offset_t)&txDMACommands[txCommandTail],
836: sizeof(enet_dma_cmd_t) );
837:
838: /*
839: * Set the transmit tail to the new stop command.
840: */
841: txCommandTail = i;
842:
843: /*
844: * Tap the DMA channel to wake it up
845: */
846: IODBDMAContinue( ioBaseEnetTxDMA );
847:
848: return true;
849: }
850:
851: /*-------------------------------------------------------------------------
852: * _receivePacket
853: * --------------
854: * This routine runs the receiver in polled-mode (yuk!) for the kernel
855: * debugger.
856: *
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: *-------------------------------------------------------------------------*/
863:
864: void MaceEnet::_receivePacket(void *pkt, unsigned int *pkt_len,
865: unsigned int timeout)
866: {
867: ns_time_t startTime;
868: ns_time_t currentTime;
869: u_int32_t elapsedTimeMS;
870:
871: if (!ready || !pkt || !pkt_len)
872: return;
873:
874: *pkt_len = 0;
875:
876: debuggerPkt = pkt;
877: debuggerPktSize = 0;
878:
879: _IOGetTimestamp(&startTime);
880: do
881: {
882: _receivePackets(true);
883: _IOGetTimestamp(¤tTime);
884: elapsedTimeMS = (currentTime - startTime) / (1000*1000);
885: }
886: while ( (debuggerPktSize == 0) && (elapsedTimeMS < timeout) );
887:
888: *pkt_len = debuggerPktSize;
889:
890: return;
891: }
892:
893: /*-------------------------------------------------------------------------
894: * _packetToDebugger
895: * -----------------
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: *-------------------------------------------------------------------------*/
900:
901: void MaceEnet::_packetToDebugger(struct mbuf * packet, u_int size)
902: {
903: debuggerPktSize = size;
904: bcopy( mtod(packet, char *), debuggerPkt, size );
905: }
906:
907: /*-------------------------------------------------------------------------
908: * _sendPacket
909: * -----------
910: *
911: * This routine runs the transmitter in polled-mode (yuk!) for the
912: * kernel debugger.
913: *
914: *-------------------------------------------------------------------------*/
915:
916: void MaceEnet::_sendPacket(void *pkt, unsigned int pkt_len)
917: {
918: ns_time_t startTime;
919: ns_time_t currentTime;
920: u_int32_t elapsedTimeMS;
921:
922: if ( !ready || !pkt || (pkt_len > ETHERMAXPACKET))
923: return;
924:
925: /*
926: * Wait for the transmit ring to empty
927: */
928: _IOGetTimestamp(&startTime);
929: do
930: {
931: _transmitInterruptOccurred(true);
932: _IOGetTimestamp(¤tTime);
933: elapsedTimeMS = (currentTime - startTime) / (1000*1000);
934: }
935: while ( (txCommandHead != txCommandTail) &&
936: (elapsedTimeMS < TX_KDB_TIMEOUT) );
937:
938: if ( txCommandHead != txCommandTail )
939: {
940: IOLog( "Mace: Polled tranmit timeout - 1\n\r");
941: return;
942: }
943:
944: txDebuggerPkt->m_next = 0;
945: txDebuggerPkt->m_data = (caddr_t) pkt;
946: txDebuggerPkt->m_pkthdr.len = txDebuggerPkt->m_len = pkt_len;
947:
948: /*
949: * Send the debugger packet. txDebuggerPkt must not be freed by
950: * the transmit routine.
951: */
952: _transmitPacket(txDebuggerPkt);
953:
954: /*
955: * Poll waiting for the transmit ring to empty again
956: */
957: do
958: {
959: _transmitInterruptOccurred(true);
960: _IOGetTimestamp(¤tTime);
961: elapsedTimeMS = (currentTime - startTime) / (1000*1000);
962: }
963: while ( (txCommandHead != txCommandTail) &&
964: (elapsedTimeMS < TX_KDB_TIMEOUT) );
965:
966: if ( txCommandHead != txCommandTail )
967: {
968: IOLog("Mace: Polled transmit timeout - 2\n\r");
969: }
970:
971: return;
972: }
973:
974: /*-------------------------------------------------------------------------
975: *
976: *
977: *
978: *-------------------------------------------------------------------------*/
979:
980: bool MaceEnet::_receiveInterruptOccurred()
981: {
982: return _receivePackets(false);
983: }
984:
985: /*-------------------------------------------------------------------------
986: *
987: *
988: *
989: *-------------------------------------------------------------------------*/
990:
991: bool MaceEnet::_receivePackets(bool fDebugger)
992: {
993: enet_dma_cmd_t tmpCommand;
994: struct mbuf * packet;
995: u_int32_t i,j,last;
996: u_int32_t dmaChnlStatus;
997: int receivedFrameSize = 0;
998: u_int32_t dmaCount[2], dmaResid[2], dmaStatus[2];
999: bool reusePkt;
1000: bool status;
1001: bool useNetif = !fDebugger && netifClient;
1002: bool packetsQueued = false;
1003: u_int8_t *rxFS = NULL;
1004: u_int32_t nextDesc;
1005: static const u_int32_t lastResetValue = (u_int32_t)(-1);
1006:
1007: last = lastResetValue;
1008: i = rxCommandHead;
1009:
1010: while ( 1 )
1011: {
1012: reusePkt = false;
1013:
1014: /*
1015: * Purge cache references for the DBDMA entry we are about to look at.
1016: */
1017: invalidate_cache_v((vm_offset_t)&rxDMACommands[i],
1018: sizeof(enet_dma_cmd_t));
1019:
1020: /*
1021: * Collect the DMA residual counts/status for the two buffer segments.
1022: */
1023: for ( j = 0; j < 2; j++ )
1024: {
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] ) &
1029: kdbdmaReqCountMask;
1030: }
1031:
1032: #if 0
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] );
1035: #endif
1036:
1037: /*
1038: * If the current entry has not been written, then stop at this entry
1039: */
1040: if ( !((dmaStatus[0] & kdbdmaBt) || (dmaStatus[1] & kdbdmaActive)) )
1041: {
1042: break;
1043: }
1044:
1045: /*
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.
1049: */
1050: receivedFrameSize = dmaCount[0] - dmaResid[0] + dmaCount[1] -
1051: ((dmaStatus[0] & kdbdmaBt) ? dmaCount[1] : dmaResid[1]);
1052:
1053: if ( ( receivedFrameSize >= 4 ) &&
1054: ( receivedFrameSize <= NETWORK_BUFSIZE ) )
1055: {
1056: /*
1057: * Get the receive frame size as reported by the Mace controller
1058: */
1059:
1060: rxFS = mtod(rxMbuf[i], u_int8_t *) + receivedFrameSize - 4;
1061:
1062: receivedFrameSize = (u_int16_t) rxFS[0] |
1063: (rxFS[1] & kRcvFS1RcvCnt) << 8;
1064: }
1065:
1066: /*
1067: * Reject packets that are runts or that have other mutations.
1068: */
1069: if ( receivedFrameSize < (ETHERMINPACKET - ETHERCRC) ||
1070: receivedFrameSize > (ETHERMAXPACKET + ETHERCRC) ||
1071: (rxFS[1] & (kRcvFS1OFlo | kRcvFS1Clsn | kRcvFS1Fram | kRcvFS1FCS))
1072: )
1073: {
1074: if (useNetif) netStats->inputErrors++;
1075: reusePkt = true;
1076: }
1077: else if ( useNetif == false )
1078: {
1079: /*
1080: * Always reuse packets in debugger mode.
1081: */
1082: reusePkt = true;
1083: if (fDebugger)
1084: _packetToDebugger(rxMbuf[i], receivedFrameSize);
1085: }
1086:
1087: /*
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.
1091: * Thanks Justin!
1092: */
1093:
1094: packet = 0;
1095:
1096: if ( reusePkt == false )
1097: {
1098: bool replaced;
1099:
1100: packet = replaceOrCopyPacket(&rxMbuf[i], receivedFrameSize,
1101: &replaced);
1102:
1103: reusePkt = true;
1104:
1105: if (packet && replaced)
1106: {
1107: status = _updateDescriptorFromMbuf(rxMbuf[i],
1108: &rxDMACommands[i], true);
1109:
1110: if (status)
1111: {
1112: reusePkt = false;
1113: }
1114: else
1115: {
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");
1121: }
1122: }
1123:
1124: if (packet == 0)
1125: netStats->inputErrors++;
1126: }
1127:
1128: /*
1129: * If we are reusing the existing mbuf, then refurbish the existing
1130: * DMA command \ descriptors by clearing the status/residual count
1131: * fields.
1132: */
1133:
1134: if ( reusePkt == true )
1135: {
1136: for ( j=0; j < sizeof(enet_dma_cmd_t)/sizeof(IODBDMADescriptor);
1137: j++ )
1138: {
1139: IOSetCCResult( &rxDMACommands[i].desc_seg[j], 0 );
1140: }
1141: flush_cache_v( (vm_offset_t)&rxDMACommands[i],
1142: sizeof(enet_dma_cmd_t) );
1143: }
1144:
1145: /*
1146: * Keep track of the last receive descriptor processed
1147: */
1148: last = i;
1149:
1150: /*
1151: * Implement ring wrap-around
1152: */
1153: if (++i >= rxMaxCommand) i = 0;
1154:
1155: /*
1156: * Early exit in debugger mode.
1157: */
1158: if (fDebugger)
1159: {
1160: break;
1161: }
1162:
1163: /*
1164: * Transfer received to network stack.
1165: */
1166: if (packet)
1167: {
1168: KERNEL_DEBUG(DBG_MACE_RXCOMPLETE | DBG_FUNC_NONE, (int) packet,
1169: (int)receivedFrameSize, 0, 0, 0 );
1170:
1171: /*
1172: * The KDB lock must be held before calling this function.
1173: */
1174: networkInterface->inputPacket(packet, receivedFrameSize, true);
1175: netStats->inputPackets++;
1176: packetsQueued = true;
1177: }
1178: }
1179:
1180: /*
1181: * OK...this is a little messy
1182: *
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.
1188: */
1189:
1190: #if 0
1191: IOLog("Mace: Prev - Rx Head = %2d Rx Tail = %2d Rx Last = %2d\n\r",
1192: rxCommandHead, rxCommandTail, last );
1193: #endif
1194:
1195: if ( last != lastResetValue )
1196: {
1197: /*
1198: * Save the contents of the last receive descriptor processed.
1199: */
1200: packet = rxMbuf[last];
1201: tmpCommand = rxDMACommands[last];
1202:
1203: /*
1204: * Write a DMA stop command into this descriptor slot
1205: */
1206: rxDMACommands[last].desc_seg[0] = dbdmaCmd_Stop;
1207: rxDMACommands[last].desc_seg[1] = dbdmaCmd_Nop;
1208: rxMbuf[last] = 0;
1209:
1210: flush_cache_v( (vm_offset_t)&rxDMACommands[last],
1211: sizeof(enet_dma_cmd_t) );
1212:
1213: /*
1214: * Replace the previous DMA stop command with the last receive
1215: * descriptor processed.
1216: *
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
1220: * command.
1221: *
1222: * Note: When relocating the descriptor, we must update its branch
1223: * field to reflect its new location.
1224: */
1225: nextDesc = rxDMACommandsPhys + (int)&rxDMACommands[rxCommandTail+1] -
1226: (int)rxDMACommands;
1227: IOSetCCCmdDep( &tmpCommand.desc_seg[0], nextDesc );
1228:
1229: bcopy( (u_int32_t *)&tmpCommand+1,
1230: (u_int32_t *)&rxDMACommands[rxCommandTail]+1,
1231: sizeof(enet_dma_cmd_t)-sizeof(u_int32_t) );
1232:
1233: flush_cache_v( (vm_offset_t)&rxDMACommands[rxCommandTail],
1234: sizeof(enet_dma_cmd_t) );
1235:
1236: rxMbuf[rxCommandTail] = packet;
1237:
1238: rxDMACommands[rxCommandTail].desc_seg[0].operation =
1239: tmpCommand.desc_seg[0].operation;
1240:
1241: flush_cache_v( (vm_offset_t)&rxDMACommands[rxCommandTail],
1242: sizeof(IODBDMADescriptor) );
1243:
1244: /*
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
1247: * command
1248: */
1249: rxCommandTail = last;
1250: rxCommandHead = i;
1251: }
1252:
1253: /*
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.
1258: *
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.
1262: */
1263: dmaChnlStatus = IOGetDBDMAChannelStatus( ioBaseEnetRxDMA );
1264: if ( dmaChnlStatus & kdbdmaDead )
1265: {
1266: /*
1267: * Read log error
1268: */
1269: if (useNetif) netStats->inputErrors++;
1270: IOLog( "Mace: Rx DMA Error - Status = %04x\n", dmaChnlStatus );
1271:
1272: /*
1273: * Reset and reinitialize chip
1274: */
1275: _restartChip(); // This must not block in debugger mode.
1276: }
1277: else
1278: {
1279: /*
1280: * Tap the DMA to wake it up
1281: */
1282: IODBDMAContinue( ioBaseEnetRxDMA );
1283: }
1284:
1285: #if 0
1286: IOLog( "Mace: New - Rx Head = %2d Rx Tail = %2d\n\r",
1287: rxCommandHead, rxCommandTail );
1288: #endif
1289:
1290: return packetsQueued;
1291: }
1292:
1293: /*-------------------------------------------------------------------------
1294: *
1295: *
1296: *
1297: *-------------------------------------------------------------------------*/
1298:
1299: bool MaceEnet::_transmitInterruptOccurred(bool fDebugger = false)
1300: {
1301: u_int32_t dmaStatus;
1302: u_int32_t xmtFS;
1303: bool fServiced = false;
1304: bool useNetif = !fDebugger && netifClient;
1305:
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.
1309: //
1310: if (fDebugger)
1311: debugTxPoll = true;
1312:
1313: while ( 1 )
1314: {
1315: /*
1316: * Purge cache references for the DBDMA entry we are about to look at.
1317: */
1318: invalidate_cache_v((vm_offset_t)&txDMACommands[txCommandHead],
1319: sizeof(enet_txdma_cmd_t));
1320:
1321: /*
1322: * Check the status of the last descriptor in this entry to see if
1323: * the DMA engine completed this entry.
1324: */
1325: dmaStatus = IOGetCCResult(
1326: &txDMACommands[txCommandHead].desc_seg[3] ) >> 16;
1327:
1328: if ( !(dmaStatus & kdbdmaActive) )
1329: {
1330: break;
1331: }
1332:
1333: fServiced = true;
1334:
1335: /*
1336: * Reset the status word for the entry we are about to process
1337: */
1338: IOSetCCResult( &txDMACommands[txCommandHead].desc_seg[3], 0 );
1339:
1340: flush_cache_v( (vm_offset_t) &txDMACommands[txCommandHead].desc_seg[3],
1341: sizeof(IODBDMADescriptor) );
1342:
1343: /*
1344: * This DMA descriptor read the transmit frame status. See what it has
1345: * to tell us.
1346: */
1347: xmtFS = IOGetCCCmdDep( &txDMACommands[txCommandHead].desc_seg[2] );
1348: if ( useNetif && (xmtFS & kXmtFSXmtSV) )
1349: {
1350: if (xmtFS & (kXmtFSUFlo | kXmtFSLCol | kXmtFSRtry | kXmtFSLCar) )
1351: {
1352: netStats->outputErrors++;
1353: }
1354: else
1355: {
1356: netStats->outputPackets++;
1357: }
1358:
1359: if (xmtFS & (kXmtFSOne | kXmtFSMore) )
1360: {
1361: netStats->collisions++;
1362: }
1363: }
1364:
1365: /*
1366: * Free the mbuf we just transmitted.
1367: */
1368: KERNEL_DEBUG(DBG_MACE_TXCOMPLETE | DBG_FUNC_NONE,
1369: (int) txMbuf[txCommandHead],
1370: (int) txMbuf[txCommandHead]->m_pkthdr.len, 0, 0, 0 );
1371:
1372: if (txMbuf[txCommandHead] != txDebuggerPkt)
1373: {
1374: if ( fDebugger )
1375: {
1376: //
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.
1380: //
1381: // During continuous debugger transmission and
1382: // interrupt polling, we expect only the txDebuggerPkt
1383: // to show up on the transmit mbuf ring.
1384: //
1385: debugQueue->enqueue( txMbuf[txCommandHead] );
1386: }
1387: else
1388: {
1389: freePacket( txMbuf[txCommandHead] );
1390: }
1391: }
1392:
1393: txMbuf[txCommandHead] = 0;
1394:
1395: if ( ++txCommandHead >= txMaxCommand ) txCommandHead = 0;
1396: }
1397:
1398: /*
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.
1403: *
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.
1407: */
1408:
1409: dmaStatus = IOGetDBDMAChannelStatus( ioBaseEnetTxDMA );
1410: if ( (dmaStatus & kdbdmaDead) || (txWDForceReset == true) )
1411: {
1412: /*
1413: * Read the transmit frame status and log error
1414: */
1415: xmtFS = ReadMaceRegister( ioBaseEnet, kXmtFS );
1416: if (useNetif) netStats->outputErrors++;
1417: IOLog( "Mace: Tx DMA Error - Status = %04x FS = %02x\n\r",
1418: dmaStatus, xmtFS);
1419:
1420: /*
1421: * Reset and reinitialize chip
1422: */
1423: _restartChip();
1424:
1425: txWDForceReset = false;
1426: fServiced = true;
1427: }
1428:
1429: return fServiced;
1430: }
1431:
1432: /*-------------------------------------------------------------------------
1433: *
1434: *
1435: *
1436: *-------------------------------------------------------------------------*/
1437:
1438: /*
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).
1444: */
1445: bool
1446: MaceEnet::_updateDescriptorFromMbuf(struct mbuf * m, enet_dma_cmd_t *desc,
1447: bool isReceive)
1448: {
1449: u_int32_t nextDesc = 0;
1450: int segments;
1451: struct IOPhysicalSegment segVector[2];
1452:
1453: /*
1454: * Although coalescing is always enabled, it cannot occur
1455: * while the driver is in debugger mode.
1456: */
1457: segments = mbufCursor->getPhysicalSegmentsWithCoalesce(m, segVector);
1458:
1459: if ((!segments) || (segments > 2)) {
1460: IOLog("Mace: _updateDescriptorFromMbuf error, %d segments\n",
1461: segments);
1462: return false;
1463: }
1464:
1465: if ( segments == 1 )
1466: {
1467: IOMakeDBDMADescriptor( (&desc->desc_seg[0]),
1468: ((isReceive) ? kdbdmaInputLast : kdbdmaOutputLast),
1469: (kdbdmaKeyStream0),
1470: (kdbdmaIntNever),
1471: (kdbdmaBranchNever),
1472: ((isReceive) ? kdbdmaWaitNever :
1473: kdbdmaWaitIfFalse),
1474: (segVector[0].length),
1475: (segVector[0].location) );
1476:
1477: desc->desc_seg[1] = (isReceive) ? dbdmaCmd_NopWInt : dbdmaCmd_Nop;
1478: }
1479: else
1480: {
1481: if ( isReceive )
1482: {
1483: nextDesc = rxDMACommandsPhys + (int)desc - (int)rxDMACommands +
1484: sizeof(enet_dma_cmd_t);
1485: }
1486:
1487: IOMakeDBDMADescriptorDep( (&desc->desc_seg[0]),
1488: ((isReceive) ? kdbdmaInputMore : kdbdmaOutputMore),
1489: (kdbdmaKeyStream0),
1490: ((isReceive) ? kdbdmaIntIfTrue : kdbdmaIntNever),
1491: ((isReceive) ? kdbdmaBranchIfTrue :
1492: kdbdmaBranchNever),
1493: (kdbdmaWaitNever),
1494: (segVector[0].length),
1495: (segVector[0].location),
1496: nextDesc );
1497:
1498: IOMakeDBDMADescriptor( (&desc->desc_seg[1]),
1499: ((isReceive) ? kdbdmaInputLast : kdbdmaOutputLast),
1500: (kdbdmaKeyStream0),
1501: ((isReceive) ? kdbdmaIntAlways : kdbdmaIntNever),
1502: (kdbdmaBranchNever),
1503: ((isReceive) ? kdbdmaWaitNever :
1504: kdbdmaWaitIfFalse),
1505: (segVector[1].length),
1506: (segVector[1].location) );
1507: }
1508:
1509: flush_cache_v( (vm_offset_t)desc, sizeof(enet_dma_cmd_t) );
1510:
1511: return true;
1512: }
1513:
1514:
1515: #ifdef DEBUG
1516: /*
1517: * Useful for testing.
1518: */
1519:
1520: void MaceEnet::_dumpDesc(void * addr, u_int32_t size)
1521: {
1522: u_int32_t i;
1523: unsigned long *p;
1524: vm_offset_t paddr;
1525:
1526: _IOPhysicalFromVirtual( (vm_offset_t) addr, (vm_offset_t *)&paddr );
1527:
1528: p = (unsigned long *)addr;
1529:
1530: for ( i=0; i < size/sizeof(IODBDMADescriptor); i++, p+=4,
1531: paddr+=sizeof(IODBDMADescriptor) )
1532: {
1533: IOLog("Ethernet(Mace): %08x(v) %08x(p): %08x %08x %08x %08x\n",
1534: (int)p,
1535: (int)paddr,
1536: (int)OSReadSwapInt32(p, 0), (int)OSReadSwapInt32(p, 4),
1537: (int)OSReadSwapInt32(p, 8), (int)OSReadSwapInt32(p, 12) );
1538: }
1539: IOLog("\n");
1540: }
1541:
1542: void MaceEnet::_dumpRegisters()
1543: {
1544: u_int8_t dataValue;
1545:
1546: IOLog("\nEthernet(Mace): IO Address = %08x", (int)ioBaseEnet );
1547:
1548: dataValue = ReadMaceRegister(ioBaseEnet, kXmtFC);
1549: IOLog("\nEthernet(Mace): Read Register %04x Transmit Frame Control = %02x", kXmtFC, dataValue );
1550:
1551: dataValue = ReadMaceRegister(ioBaseEnet, kXmtFS);
1552: IOLog("\nEthernet(Mace): Read Register %04x Transmit Frame Status = %02x", kXmtFS, dataValue );
1553:
1554: dataValue = ReadMaceRegister(ioBaseEnet, kXmtRC);
1555: IOLog("\nEthernet(Mace): Read Register %04x Transmit Retry Count = %02x", kXmtRC, dataValue );
1556:
1557: dataValue = ReadMaceRegister(ioBaseEnet, kRcvFC);
1558: IOLog("\nEthernet(Mace): Read Register %04x Receive Frame Control = %02x", kRcvFC, dataValue );
1559:
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 );
1568:
1569: dataValue = ReadMaceRegister(ioBaseEnet, kFifoFC);
1570: IOLog("\nEthernet(Mace): Read Register %04x FIFO Frame Count = %02x", kFifoFC, dataValue );
1571:
1572: dataValue = ReadMaceRegister(ioBaseEnet, kIntReg);
1573: IOLog("\nEthernet(Mace): Read Register %04x Interrupt Register = %02x", kIntReg, dataValue );
1574:
1575: dataValue = ReadMaceRegister(ioBaseEnet, kIntMask);
1576: IOLog("\nEthernet(Mace): Read Register %04x Interrupt Mask Register = %02x", kIntMask, dataValue );
1577:
1578: dataValue = ReadMaceRegister(ioBaseEnet, kPollReg);
1579: IOLog("\nEthernet(Mace): Read Register %04x Poll Register = %02x", kPollReg, dataValue );
1580:
1581: dataValue = ReadMaceRegister(ioBaseEnet, kBIUCC);
1582: IOLog("\nEthernet(Mace): Read Register %04x BUI Configuration Control = %02x", kBIUCC, dataValue );
1583:
1584: dataValue = ReadMaceRegister(ioBaseEnet, kFifoCC);
1585: IOLog("\nEthernet(Mace): Read Register %04x FIFO Configuration Control = %02x", kFifoCC, dataValue );
1586:
1587: dataValue = ReadMaceRegister(ioBaseEnet, kMacCC);
1588: IOLog("\nEthernet(Mace): Read Register %04x MAC Configuration Control = %02x", kMacCC, dataValue );
1589:
1590: dataValue = ReadMaceRegister(ioBaseEnet, kPLSCC);
1591: IOLog("\nEthernet(Mace): Read Register %04x PLS Configuration Contro = %02x", kPLSCC, dataValue );
1592:
1593: dataValue = ReadMaceRegister(ioBaseEnet, kPHYCC);
1594: IOLog("\nEthernet(Mace): Read Register %04x PHY Configuration Control = %02x", kPHYCC, dataValue );
1595:
1596: dataValue = ReadMaceRegister(ioBaseEnet, kMaceChipId0);
1597: IOLog("\nEthernet(Mace): Read Register %04x MACE ChipID Register 7:0 = %02x", kMaceChipId0, dataValue );
1598:
1599: dataValue = ReadMaceRegister(ioBaseEnet, kMaceChipId1);
1600: IOLog("\nEthernet(Mace): Read Register %04x MACE ChipID Register 15:8 = %02x", kMaceChipId1, dataValue );
1601:
1602: dataValue = ReadMaceRegister(ioBaseEnet, kMPC);
1603: IOLog("\nEthernet(Mace): Read Register %04x Missed Packet Count = %02x", kMPC, dataValue );
1604:
1605: dataValue = ReadMaceRegister(ioBaseEnet, kUTR);
1606: IOLog("\nEthernet(Mace): Read Register %04x User Test Register = %02x", kUTR, dataValue );
1607: IOLog("\nEthernet(Mace): -------------------------------------------------------\n" );
1608: }
1609: #endif DEBUG
1610:
1611:
1612: /*-------------------------------------------------------------------------
1613: *
1614: *
1615: *
1616: *-------------------------------------------------------------------------*/
1617:
1618: IOReturn MaceEnet::getHardwareAddress(enet_addr_t *ea)
1619: {
1620: unsigned char data;
1621:
1622: for (UInt i = 0; i < sizeof(*ea); i++)
1623: {
1624: data = ((unsigned char *)ioBaseEnetROM)[i << 4];
1625: ea->ea_byte[i] = reverseBitOrder(data);
1626: }
1627:
1628: return kIOReturnSuccess;
1629: }
1630:
1631: /*-------------------------------------------------------------------------
1632: *
1633: *
1634: *
1635: *-------------------------------------------------------------------------*/
1636:
1637: #define ENET_CRCPOLY 0x04c11db7
1638:
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
1649: };
1650:
1651: static u_int32_t crc416(unsigned int current, unsigned short nxtval )
1652: {
1653: register unsigned int counter;
1654: register int highCRCBitSet, lowDataBitSet;
1655:
1656: /* Swap bytes */
1657: nxtval = ((nxtval & 0x00FF) << 8) | (nxtval >> 8);
1658:
1659: /* Compute bit-by-bit */
1660: for (counter = 0; counter != 16; ++counter)
1661: { /* is high CRC bit set? */
1662: if ((current & 0x80000000) == 0)
1663: highCRCBitSet = 0;
1664: else
1665: highCRCBitSet = 1;
1666:
1667: current = current << 1;
1668:
1669: if ((nxtval & 0x0001) == 0)
1670: lowDataBitSet = 0;
1671: else
1672: lowDataBitSet = 1;
1673:
1674: nxtval = nxtval >> 1;
1675:
1676: /* do the XOR */
1677: if (highCRCBitSet ^ lowDataBitSet)
1678: current = current ^ ENET_CRCPOLY;
1679: }
1680: return current;
1681: }
1682:
1683: /*-------------------------------------------------------------------------
1684: *
1685: *
1686: *
1687: *-------------------------------------------------------------------------*/
1688:
1689: static u_int32_t mace_crc(unsigned short *address)
1690: {
1691: register u_int32_t newcrc;
1692:
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 */
1696:
1697: return (newcrc);
1698: }
1699:
1700: /*
1701: * Clear the hash table filter.
1702: *
1703: */
1704: void MaceEnet::_resetHashTableMask()
1705: {
1706: bzero(hashTableUseCount, sizeof(hashTableUseCount));
1707: bzero(hashTableMask, sizeof(hashTableMask));
1708: }
1709:
1710: /*
1711: * Add requested mcast addr to Mace's hash table filter.
1712: *
1713: */
1714: void MaceEnet::_addToHashTableMask(u_int8_t *addr)
1715: {
1716: u_int32_t crc;
1717: u_int8_t mask;
1718:
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 */
1723: mask = crc % 8;
1724: mask = (unsigned char) 1 << mask;
1725: hashTableMask[crc/8] |= mask;
1726: }
1727:
1728: /*-------------------------------------------------------------------------
1729: *
1730: *
1731: *
1732: *-------------------------------------------------------------------------*/
1733:
1734: void MaceEnet::_removeFromHashTableMask(u_int8_t *addr)
1735: {
1736: unsigned int crc;
1737: unsigned char mask;
1738:
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! */
1744:
1745: if (--hashTableUseCount[crc])
1746: return; /* That bit is still in use */
1747:
1748: mask = crc % 8;
1749: mask = ((unsigned char)1 << mask) ^ 0xffff; /* To turn off bit */
1750: hashTableMask[crc/8] &= mask;
1751: }
1752:
1753: /*
1754: * Sync the adapter with the software copy of the multicast mask
1755: * (logical address filter).
1756: */
1757: void MaceEnet::_updateHashTableMask()
1758: {
1759: u_int8_t status;
1760: u_int32_t i;
1761: u_int8_t *p;
1762: u_int8_t MacCCReg;
1763:
1764: // Stop the receiver before changing the filter.
1765: //
1766: MacCCReg = ReadMaceRegister( ioBaseEnet, kMacCC );
1767: WriteMaceRegister( ioBaseEnet, kMacCC, MacCCReg & ~kMacCCEnRcv );
1768: IODelay( RECEIVE_QUIESCE_uS );
1769:
1770: if ( chipId != kMaceRevisionA2 )
1771: {
1772: WriteMaceRegister( ioBaseEnet, kIAC, kIACAddrChg | kIACLogAddr );
1773: do
1774: {
1775: status = ReadMaceRegister( ioBaseEnet, kIAC );
1776: }
1777: while( status & kIACAddrChg );
1778: }
1779: else
1780: {
1781: WriteMaceRegister( ioBaseEnet, kIAC, kIACLogAddr );
1782: }
1783:
1784: p = (u_int8_t *) hashTableMask;
1785: for (i = 0; i < 8; i++, p++ )
1786: {
1787: WriteMaceRegister( ioBaseEnet, kLADRF, *p );
1788: }
1789:
1790: // Restore the engine's state.
1791: //
1792: WriteMaceRegister( ioBaseEnet, kMacCC, MacCCReg );
1793: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.