]> git.saurik.com Git - apple/xnu.git/blob - iokit/Drivers/network/drvMaceEnet/MaceEnet.cpp
778daebe28a6c089650804bc5745a5c3c6b639f1
[apple/xnu.git] / iokit / Drivers / network / drvMaceEnet / MaceEnet.cpp
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 * Hardware independent (relatively) code for the Mace Ethernet Controller
26 *
27 * HISTORY
28 *
29 * dd-mmm-yy
30 * Created.
31 *
32 */
33
34 #include <IOKit/assert.h>
35 #include <IOKit/platform/AppleMacIODevice.h>
36 #include "MaceEnetPrivate.h"
37
38 //------------------------------------------------------------------------
39
40 #define super IOEthernetController
41
42 OSDefineMetaClassAndStructors( MaceEnet, IOEthernetController )
43
44 //------------------------------------------------------------------------
45
46 #define PROVIDER_DEV 0
47 #define PROVIDER_DMA_TX 1
48 #define PROVIDER_DMA_RX 2
49
50 /*
51 * Public Instance Methods
52 */
53
54 bool MaceEnet::init(OSDictionary * properties)
55 {
56 if (!super::init(properties))
57 return false;
58
59 isPromiscuous = false;
60 multicastEnabled = false;
61 ready = false;
62 debugClient = false;
63 debugTxPoll = false;
64 netifClient = false;
65
66 return true;
67 }
68
69 MaceEnet * MaceEnet::probe(IOService * /*provider*/,
70 unsigned int * /*score*/,
71 unsigned int * /*specificity*/)
72 {
73 #ifdef OLD_CODE
74 extern int kdp_flag;
75
76 /*
77 * If bootargs: kdp bit 0 using in-kernel mace driver for early debugging,
78 * Don't probe this driver.
79 */
80 if( kdp_flag & 1)
81 {
82 return 0;
83 }
84 #endif
85
86 return this;
87 }
88
89 bool MaceEnet::start(IOService * provider)
90 {
91 AppleMacIODevice *nub = OSDynamicCast(AppleMacIODevice, provider);
92
93 if (!nub || !super::start(provider))
94 return false;
95
96 transmitQueue = OSDynamicCast(IOGatedOutputQueue, getOutputQueue());
97 if (!transmitQueue)
98 {
99 IOLog("Mace: output queue initialization failed\n");
100 return false;
101 }
102 transmitQueue->retain();
103
104 // Allocate debug queue. This stores packets retired from the TX ring
105 // by the polling routine. We cannot call freePacket() or m_free() within
106 // the debugger context.
107 //
108 // The capacity of the queue is set at maximum to prevent the queue from
109 // calling m_free() due to over-capacity. But we don't expect the size
110 // of the queue to grow too large.
111 //
112 debugQueue = IOPacketQueue::withCapacity((UInt) -1);
113 if (!debugQueue)
114 return false;
115
116 // Allocate a IOMbufBigMemoryCursor instance. Currently, the maximum
117 // number of segments is set to 2. The maximum length for each segment
118 // is set to the maximum ethernet frame size (plus padding).
119
120 mbufCursor = IOMbufBigMemoryCursor::withSpecification(NETWORK_BUFSIZE, 2);
121 if (!mbufCursor)
122 {
123 IOLog("Mace: IOMbufMemoryCursor allocation failed\n");
124 return false;
125 }
126
127 //
128 // Our provider is the nub representing the MaceEnet hardware
129 // controller. We will query it for our resource information.
130 //
131
132 for (int i = 0; i < MEMORY_MAP_COUNT; i++) {
133 IOMemoryMap * map;
134
135 map = provider->mapDeviceMemoryWithIndex(i);
136 if (!map)
137 return false;
138
139 #ifdef DEBUG_XXX
140 IOLog("map %d: Phys:%08x Virt:%08x len:%d\n",
141 i,
142 (UInt) map->getPhysicalAddress(),
143 (UInt) map->getVirtualAddress(),
144 (UInt) map->getLength());
145 #endif
146
147 switch (i) {
148 case MEMORY_MAP_ENET_INDEX:
149 ioBaseEnet = (IOPPCAddress) map->getVirtualAddress();
150 ioBaseEnetROM = (IOPPCAddress) ((map->getPhysicalAddress() &
151 ~0xffff) | kControllerROMOffset);
152 break;
153
154 case MEMORY_MAP_TXDMA_INDEX:
155 ioBaseEnetTxDMA = (IODBDMAChannelRegisters *)
156 map->getVirtualAddress();
157 break;
158
159 case MEMORY_MAP_RXDMA_INDEX:
160 ioBaseEnetRxDMA = (IODBDMAChannelRegisters *)
161 map->getVirtualAddress();
162 break;
163 }
164
165 maps[i] = map;
166 }
167
168 // Manually create an IODeviceMemory for the ROM memory
169 // range.
170 //
171 IODeviceMemory * romMemory = IODeviceMemory::withRange(
172 (UInt) ioBaseEnetROM, 0x1000);
173 if (!romMemory) {
174 IOLog("Mace: can't create ROM memory object\n");
175 return false;
176 }
177
178 romMap = romMemory->map();
179 romMemory->release();
180
181 if (!romMap)
182 return false;
183
184 ioBaseEnetROM = (IOPPCAddress) romMap->getVirtualAddress();
185
186 #ifdef DEBUG_XXX
187 IOLog("Mace: ioBaseEnet : %08x\n", (UInt) ioBaseEnet);
188 IOLog("Mace: ioBaseEnetTxDMA : %08x\n", (UInt) ioBaseEnetTxDMA);
189 IOLog("Mace: ioBaseEnetRxDMA : %08x\n", (UInt) ioBaseEnetRxDMA);
190 IOLog("Mace: ioBaseEnetROM : %08x\n", (UInt) ioBaseEnetROM);
191 #endif
192
193 //
194 // Get a reference to the IOWorkLoop in our superclass.
195 //
196 IOWorkLoop * myWorkLoop = (IOWorkLoop *) getWorkLoop();
197 assert(myWorkLoop);
198
199 //
200 // Allocate two IOInterruptEventSources.
201 //
202 txIntSrc = IOInterruptEventSource::interruptEventSource
203 (this,
204 (IOInterruptEventAction) &MaceEnet::interruptOccurredForSource,
205 provider, PROVIDER_DMA_TX);
206 if (!txIntSrc
207 || (myWorkLoop->addEventSource(txIntSrc) != kIOReturnSuccess)) {
208 IOLog("Mace: txIntSrc init failure\n");
209 return false;
210 }
211
212 rxIntSrc = IOInterruptEventSource::interruptEventSource
213 (this,
214 (IOInterruptEventAction) &MaceEnet::interruptOccurredForSource,
215 provider, PROVIDER_DMA_RX);
216 if (!rxIntSrc
217 || (myWorkLoop->addEventSource(rxIntSrc) != kIOReturnSuccess)) {
218 IOLog("Mace: rxIntSrc init failure\n");
219 return false;
220 }
221
222 timerSrc = IOTimerEventSource::timerEventSource
223 (this, (IOTimerEventSource::Action) &MaceEnet::timeoutOccurred);
224 if (!timerSrc
225 || (myWorkLoop->addEventSource(timerSrc) != kIOReturnSuccess)) {
226 IOLog("Mace: timerSrc init failure\n");
227 return false;
228 }
229
230 MGETHDR(txDebuggerPkt, M_DONTWAIT, MT_DATA);
231 if (!txDebuggerPkt)
232 {
233 IOLog("Mace: Can't allocate KDB buffer\n");
234 return false;
235 }
236
237 #if 0
238 // Do not enable interrupt sources until the hardware
239 // is enabled.
240
241 // Enable the interrupt event sources.
242 myWorkLoop->enableAllInterrupts();
243 #endif
244
245 #if 0
246 // Do not reset the hardware until we are ready to use it.
247 // Otherwise, we would have messed up kdp_mace driver's
248 // state. And we won't be able to break into the debugger
249 // until we attach our debugger client.
250
251 //
252 // Perform a hardware reset.
253 //
254 if ( !resetAndEnable(false) )
255 {
256 return false;
257 }
258 #endif
259
260 // Cache my MAC address.
261 //
262 getHardwareAddress(&myAddress);
263
264 //
265 // Allocate memory for ring buffers.
266 //
267 if (_allocateMemory() == false)
268 {
269 return false;
270 }
271
272 //
273 // Attach a kernel debugger client.
274 //
275 attachDebuggerClient(&debugger);
276
277 //
278 // Allocate and initialize an IONetworkInterface object.
279 //
280 if (!attachInterface((IONetworkInterface **) &networkInterface))
281 return false;
282
283 return true;
284 }
285
286 /*-------------------------------------------------------------------------
287 *
288 *
289 *
290 *-------------------------------------------------------------------------*/
291
292 void MaceEnet::free()
293 {
294 UInt i;
295
296 timerSrc->cancelTimeout();
297
298 _resetChip();
299
300 if (debugger)
301 debugger->release();
302
303 if (timerSrc)
304 timerSrc->release();
305
306 if (rxIntSrc)
307 rxIntSrc->release();
308
309 if (txIntSrc)
310 txIntSrc->release();
311
312 if (transmitQueue)
313 transmitQueue->release();
314
315 if (debugQueue)
316 debugQueue->release();
317
318 if (networkInterface)
319 networkInterface->release();
320
321 if (mbufCursor)
322 mbufCursor->release();
323
324 if (txDebuggerPkt)
325 freePacket(txDebuggerPkt);
326
327 for (i = 0; i < rxMaxCommand; i++)
328 if (rxMbuf[i]) freePacket(rxMbuf[i]);
329
330 for (i = 0; i < txMaxCommand; i++)
331 if (txMbuf[i]) freePacket(txMbuf[i]);
332
333 if (romMap) romMap->release();
334
335 for (i = 0; i < MEMORY_MAP_COUNT; i++)
336 if (maps[i]) maps[i]->release();
337
338 if (dmaMemory.ptr)
339 {
340 IOFree(dmaMemory.ptrReal, dmaMemory.sizeReal);
341 dmaMemory.ptr = 0;
342 }
343
344 if ( workLoop )
345 {
346 workLoop->release();
347 workLoop = 0;
348 }
349
350 super::free();
351 }
352
353 /*-------------------------------------------------------------------------
354 * Override IONetworkController::createWorkLoop() method and create
355 * a workloop.
356 *
357 *-------------------------------------------------------------------------*/
358
359 bool MaceEnet::createWorkLoop()
360 {
361 workLoop = IOWorkLoop::workLoop();
362
363 return ( workLoop != 0 );
364 }
365
366 /*-------------------------------------------------------------------------
367 * Override IOService::getWorkLoop() method to return our workloop.
368 *
369 *
370 *-------------------------------------------------------------------------*/
371
372 IOWorkLoop * MaceEnet::getWorkLoop() const
373 {
374 return workLoop;
375 }
376
377 /*-------------------------------------------------------------------------
378 *
379 *
380 *
381 *-------------------------------------------------------------------------*/
382
383 void MaceEnet::interruptOccurredForSource(IOInterruptEventSource *src,
384 int /*count*/)
385 {
386 bool doFlushQueue = false;
387 bool doService = false;
388
389 // IOLog("Mace: interrupt %08x %d\n", (UInt) src, count);
390
391 if (!ready) {
392 // IOLog("Mace: unexpected interrupt\n");
393 return;
394 }
395
396 reserveDebuggerLock();
397
398 if (src == txIntSrc) {
399 txWDInterrupts++;
400 KERNEL_DEBUG(DBG_MACE_TXIRQ | DBG_FUNC_START, 0, 0, 0, 0, 0 );
401 doService = _transmitInterruptOccurred();
402 KERNEL_DEBUG(DBG_MACE_TXIRQ | DBG_FUNC_END, 0, 0, 0, 0, 0 );
403 }
404 else {
405 KERNEL_DEBUG(DBG_MACE_RXIRQ | DBG_FUNC_START, 0, 0, 0, 0, 0 );
406 doFlushQueue = _receiveInterruptOccurred();
407 KERNEL_DEBUG(DBG_MACE_RXIRQ | DBG_FUNC_END, 0, 0, 0, 0, 0 );
408 }
409
410 releaseDebuggerLock();
411
412 /*
413 * Submit all received packets queued up by _receiveInterruptOccurred()
414 * to the network stack. The up call is performed without holding the
415 * debugger lock.
416 */
417 if (doFlushQueue)
418 networkInterface->flushInputQueue();
419
420 /*
421 * Make sure the output queue is not stalled.
422 */
423 if (doService && netifClient)
424 transmitQueue->service();
425 }
426
427 /*-------------------------------------------------------------------------
428 *
429 *
430 *
431 *-------------------------------------------------------------------------*/
432
433 UInt32 MaceEnet::outputPacket(struct mbuf *pkt, void *param)
434 {
435 u_int32_t i;
436 u_int8_t regValue;
437 UInt32 ret = kIOReturnOutputSuccess;
438
439 // IOLog("Mace: outputPacket %d\n", pkt->m_pkthdr.len);
440
441 KERNEL_DEBUG(DBG_MACE_TXQUEUE | DBG_FUNC_NONE, (int) pkt,
442 (int) pkt->m_pkthdr.len, 0, 0, 0 );
443
444 /*
445 * Hold the debugger lock so the debugger can't interrupt us
446 */
447 reserveDebuggerLock();
448
449 do
450 {
451 /*
452 * Someone is turning off the receiver before the first transmit.
453 * Dont know who yet!
454 */
455 regValue = ReadMaceRegister( ioBaseEnet, kMacCC );
456 regValue |= kMacCCEnRcv;
457 WriteMaceRegister( ioBaseEnet, kMacCC, regValue );
458
459 /*
460 * Preliminary sanity checks
461 */
462 assert(pkt && netifClient);
463
464 /*
465 * Remove any completed packets from the Tx ring
466 */
467 _transmitInterruptOccurred();
468
469 i = txCommandTail + 1;
470 if ( i >= txMaxCommand ) i = 0;
471 if ( i == txCommandHead )
472 {
473 ret = kIOReturnOutputStall;
474 continue;
475 }
476
477 /*
478 * If there is space on the Tx ring, add the packet directly to the
479 * ring
480 */
481 _transmitPacket(pkt);
482 }
483 while ( 0 );
484
485 releaseDebuggerLock();
486
487 return ret;
488 }
489
490 /*-------------------------------------------------------------------------
491 * Called by IOEthernetInterface client to enable the controller.
492 * This method is always called while running on the default workloop
493 * thread.
494 *-------------------------------------------------------------------------*/
495
496 IOReturn MaceEnet::enable(IONetworkInterface * netif)
497 {
498 IONetworkParameter * param;
499
500 // If an interface client has previously enabled us,
501 // and we know there can only be one interface client
502 // for this driver, then simply return true.
503 //
504 if (netifClient) {
505 IOLog("Mace: already enabled\n");
506 return kIOReturnSuccess;
507 }
508
509 param = netif->getParameter(kIONetworkStatsKey);
510 if (!param || !(netStats = (IONetworkStats *) param->getBuffer()))
511 {
512 IOLog("Mace: invalid network statistics\n");
513 return kIOReturnError;
514 }
515
516 if ((ready == false) && !resetAndEnable(true))
517 return kIOReturnIOError;
518
519 // Record the interface as an active client.
520 //
521 netifClient = true;
522
523 // Start our IOOutputQueue object.
524 //
525 transmitQueue->setCapacity(TRANSMIT_QUEUE_SIZE);
526 transmitQueue->start();
527
528 return kIOReturnSuccess;
529 }
530
531 /*-------------------------------------------------------------------------
532 * Called by IOEthernetInterface client to disable the controller.
533 * This method is always called while running on the default workloop
534 * thread.
535 *-------------------------------------------------------------------------*/
536
537 IOReturn MaceEnet::disable(IONetworkInterface * /*netif*/)
538 {
539 // If we have no active clients, then disable the controller.
540 //
541 if (debugClient == false)
542 resetAndEnable(false);
543
544 // Disable our IOOutputQueue object.
545 //
546 transmitQueue->stop();
547
548 // Flush all packets currently in the output queue.
549 //
550 transmitQueue->setCapacity(0);
551 transmitQueue->flush();
552
553 netifClient = false;
554
555 return kIOReturnSuccess;
556 }
557
558 /*-------------------------------------------------------------------------
559 * This method is called by our debugger client to bring up the controller
560 * just before the controller is registered as the debugger device. The
561 * debugger client is attached in response to the attachDebuggerClient()
562 * call.
563 *
564 * This method is always called while running on the default workloop
565 * thread.
566 *-------------------------------------------------------------------------*/
567
568 IOReturn MaceEnet::enable(IOKernelDebugger * /*debugger*/)
569 {
570 // Enable hardware and make it ready to support the debugger client.
571 //
572 if ((ready == false) && !resetAndEnable(true))
573 return kIOReturnIOError;
574
575 // Record the debugger as an active client of ours.
576 //
577 debugClient = true;
578
579 // Returning true will allow the kdp registration to continue.
580 // If we return false, then we will not be registered as the
581 // debugger device, and the attachDebuggerClient() call will
582 // return NULL.
583 //
584 return kIOReturnSuccess;
585 }
586
587 /*-------------------------------------------------------------------------
588 * This method is called by our debugger client to stop the controller.
589 * The debugger will call this method when we issue a detachDebuggerClient().
590 *
591 * This method is always called while running on the default workloop
592 * thread.
593 *-------------------------------------------------------------------------*/
594
595 IOReturn MaceEnet::disable(IOKernelDebugger * /*debugger*/)
596 {
597 debugClient = false;
598
599 // If we have no active clients, then disable the controller.
600 //
601 if (netifClient == false)
602 resetAndEnable(false);
603
604 return kIOReturnSuccess;
605 }
606
607 /*-------------------------------------------------------------------------
608 *
609 *
610 *
611 *-------------------------------------------------------------------------*/
612
613 bool MaceEnet::resetAndEnable(bool enable)
614 {
615 bool ret = true;
616
617 if (timerSrc)
618 timerSrc->cancelTimeout();
619
620 _disableAdapterInterrupts();
621 if (getWorkLoop()) getWorkLoop()->disableAllInterrupts();
622
623 reserveDebuggerLock();
624
625 ready = false;
626
627 _resetChip();
628
629 do {
630 if (!enable) break;
631
632 if ( !_initRxRing() || !_initTxRing() || !_initChip() )
633 {
634 ret = false;
635 break;
636 }
637
638 _startChip();
639
640 ready = true;
641
642 releaseDebuggerLock();
643
644 timerSrc->setTimeoutMS(WATCHDOG_TIMER_MS);
645
646 if (getWorkLoop()) getWorkLoop()->enableAllInterrupts();
647 _enableAdapterInterrupts();
648
649 return true;
650 }
651 while (0);
652
653 releaseDebuggerLock();
654
655 return ret;
656 }
657
658 /*-------------------------------------------------------------------------
659 *
660 *
661 *
662 *-------------------------------------------------------------------------*/
663
664 void MaceEnet::_sendTestPacket()
665 {
666 // IOOutputPacketStatus ret;
667 unsigned char * buf;
668 const unsigned int size = 64;
669
670 struct mbuf * m = allocatePacket(size);
671 if (!m) {
672 IOLog("Mace: _sendTestpacket: allocatePacket() failed\n");
673 return;
674 }
675
676 buf = mtod(m, unsigned char *);
677
678 bcopy(&myAddress, buf, NUM_EN_ADDR_BYTES);
679 buf += NUM_EN_ADDR_BYTES;
680 bcopy(&myAddress, buf, NUM_EN_ADDR_BYTES);
681 buf += NUM_EN_ADDR_BYTES;
682 *buf++ = 0;
683 *buf++ = 0;
684
685 outputPacket(m, 0);
686 }
687
688 /*-------------------------------------------------------------------------
689 *
690 *
691 *
692 *-------------------------------------------------------------------------*/
693
694 void MaceEnet::timeoutOccurred(IOTimerEventSource * /*timer*/)
695 {
696 u_int32_t dmaStatus;
697 bool doFlushQueue = false;
698 bool doService = false;
699
700 reserveDebuggerLock();
701
702 /*
703 * Check for DMA shutdown on receive channel
704 */
705 dmaStatus = IOGetDBDMAChannelStatus( ioBaseEnetRxDMA );
706 if ( !(dmaStatus & kdbdmaActive) )
707 {
708 #if 0
709 IOLog("Mace: Timeout check - RxHead = %d RxTail = %d\n",
710 rxCommandHead, rxCommandTail);
711 #endif
712
713 #if 0
714 IOLog( "Mace: Rx Commands = %08x(p) Rx DMA Ptr = %08x(p)\n\r", rxDMACommandsPhys, IOGetDBDMACommandPtr(ioBaseEnetRxDMA) );
715 [self _dumpDesc:(void *)rxDMACommands Size:rxMaxCommand * sizeof(enet_dma_cmd_t)];
716 #endif
717
718 doFlushQueue = _receiveInterruptOccurred();
719 }
720
721 /*
722 * If there are pending entries on the Tx ring
723 */
724 if ( txCommandHead != txCommandTail )
725 {
726 /*
727 * If we did not service the Tx ring during the last timeout interval,
728 * then force servicing of the Tx ring.
729 * If we have more than one timeout interval without any transmit
730 * interrupts, then force the transmitter to reset.
731 */
732 if ( txWDInterrupts == 0 )
733 {
734 if ( ++txWDTimeouts > 1 ) txWDForceReset = true;
735
736 #if 0
737 IOLog( "Mace: Checking for timeout - TxHead = %d TxTail = %d\n",
738 txCommandHead, txCommandTail);
739 #endif
740 doService = _transmitInterruptOccurred();
741 }
742 else
743 {
744 txWDTimeouts = 0;
745 txWDInterrupts = 0;
746 }
747 }
748 else
749 {
750 txWDTimeouts = 0;
751 txWDInterrupts = 0;
752 }
753
754 // Clean-up after the debugger if the debugger was active.
755 //
756 if (debugTxPoll)
757 {
758 debugQueue->flush();
759 debugTxPoll = false;
760 releaseDebuggerLock();
761 doService = true;
762 }
763 else
764 {
765 releaseDebuggerLock();
766 }
767
768 /*
769 * Submit all received packets queued up by _receiveInterruptOccurred()
770 * to the network stack. The up call is performed without holding the
771 * debugger lock.
772 */
773 if (doFlushQueue)
774 {
775 networkInterface->flushInputQueue();
776 }
777
778 /*
779 * Make sure the output queue is not stalled.
780 */
781 if (doService && netifClient)
782 {
783 transmitQueue->service();
784 }
785
786 /*
787 * Restart the watchdog timer
788 */
789 timerSrc->setTimeoutMS(WATCHDOG_TIMER_MS);
790 }
791
792 /*-------------------------------------------------------------------------
793 *
794 *
795 *
796 *-------------------------------------------------------------------------*/
797
798 const OSString * MaceEnet::newVendorString() const
799 {
800 return OSString::withCString("Apple");
801 }
802
803 const OSString * MaceEnet::newModelString() const
804 {
805 return OSString::withCString("Mace");
806 }
807
808 const OSString * MaceEnet::newRevisionString() const
809 {
810 return OSString::withCString("");
811 }
812
813 /*-------------------------------------------------------------------------
814 *
815 *
816 *
817 *-------------------------------------------------------------------------*/
818
819 IOReturn MaceEnet::_setPromiscuousMode(IOEnetPromiscuousMode mode)
820 {
821 u_int8_t regVal;
822
823 regVal = ReadMaceRegister( ioBaseEnet, kMacCC );
824 WriteMaceRegister( ioBaseEnet, kMacCC, regVal & ~kMacCCEnRcv );
825 if (mode == kIOEnetPromiscuousModeOff) {
826 regVal &= ~kMacCCProm;
827 isPromiscuous = false;
828 }
829 else {
830 regVal |= kMacCCProm;
831 isPromiscuous = true;
832 }
833 WriteMaceRegister( ioBaseEnet, kMacCC, regVal );
834
835 return kIOReturnSuccess;
836
837 }
838
839 IOReturn MaceEnet::setPromiscuousMode(IOEnetPromiscuousMode mode)
840 {
841 IOReturn ret;
842
843 reserveDebuggerLock();
844 ret = _setPromiscuousMode(mode);
845 releaseDebuggerLock();
846
847 return ret;
848 }
849
850 IOReturn MaceEnet::setMulticastMode(IOEnetMulticastMode mode)
851 {
852 multicastEnabled = (mode == kIOEnetMulticastModeOff) ? false : true;
853 return kIOReturnSuccess;
854 }
855
856 IOReturn MaceEnet::setMulticastList(IOEthernetAddress *addrs, UInt32 count)
857 {
858 reserveDebuggerLock();
859 _resetHashTableMask();
860 for (UInt32 i = 0; i < count; i++) {
861 _addToHashTableMask(addrs->bytes);
862 addrs++;
863 }
864 _updateHashTableMask();
865 releaseDebuggerLock();
866 return kIOReturnSuccess;
867 }
868
869 /*
870 * Allocate an IOOutputQueue object.
871 */
872 IOOutputQueue * MaceEnet::createOutputQueue()
873 {
874 return IOGatedOutputQueue::withTarget( this, getWorkLoop() );
875 }
876
877 /*
878 * Kernel Debugger Support
879 */
880 void MaceEnet::sendPacket(void *pkt, UInt32 pkt_len)
881 {
882 _sendPacket(pkt, pkt_len);
883 }
884
885 void MaceEnet::receivePacket(void *pkt, UInt32 *pkt_len, UInt32 timeout)
886 {
887 _receivePacket(pkt, (UInt *) pkt_len, timeout);
888 }
889
890 #if 0 // no power management stuff in IOKit yet.
891 /*
892 * Power management methods.
893 */
894 - (IOReturn)getPowerState:(PMPowerState *)state_p
895 {
896 return kIOReturnUnsupported;
897 }
898
899 - (IOReturn)setPowerState:(PMPowerState)state
900 {
901 if (state == PM_OFF) {
902 resetAndEnabled = NO;
903 [self _resetChip];
904 return kIOReturnSuccess;
905 }
906 return kIOReturnUnsupported;
907 }
908
909 - (IOReturn)getPowerManagement:(PMPowerManagementState *)state_p
910 {
911 return kIOReturnUnsupported;
912 }
913
914 - (IOReturn)setPowerManagement:(PMPowerManagementState)state
915 {
916 return kIOReturnUnsupported;
917 }
918 #endif /* 0 */