|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1995-1996 NeXT Software, Inc.
27: *
28: * Implementation for hardware dependent (relatively) code
29: * for the DECchip 21040 and 21041.
30: *
31: * HISTORY
32: *
33: * 26-Apr-95 Rakesh Dubey (rdubey) at NeXT
34: * Created.
35: * 11-Oct-95 Dieter Siegmund (dieter) at NeXT
36: * Added performance hooks; changed transmit interrupt
37: * to only interrupt every N / 2 times, where N is the
38: * number of transmit descriptors. This reduces the
39: * number of interrupts taken, and the amount of CPU
40: * used by the driver.
41: * 02-Nov-95 Rakesh Dubey (rdubey) at NeXT
42: * Added support for 21041 based adapters.
43: * -- serial ROM for station address
44: * -- new network interface selection scheme
45: * 11-Dec-95 Dieter Siegmund (dieter) at NeXT
46: * Split out 21040 and 21041 connector auto-detect logic.
47: * 07-Feb-96 Dieter Siegmund (dieter) at NeXT
48: * Fixed multicast.
49: * 25-Jun-96 Dieter Siegmund (dieter) at NeXT
50: * Added kernel debugger support.
51: * 05-Aug-97 Joe Liu at Apple
52: * Made kernel debugger support more robust.
53: */
54:
55: #import "DECchip2104x.h"
56: #import "DECchip2104xPrivate.h"
57:
58: #import <machdep/ppc/proc_reg.h>
59: #import <mach/vm_param.h> // PAGE_SIZE
60:
61: extern void *kernel_map;
62: extern kern_return_t kmem_alloc_wired();
63:
64: //#define DEBUG
65:
66: #import "DECchip2104xInline.h"
67:
68: #ifdef DEBUG
69: static void IOBreak()
70: {
71: //IOBreakToDebugger();
72: return;
73: }
74:
75: static void printDesc(void *descriptorStruct)
76: {
77: txDescriptorStruct *desc = (txDescriptorStruct *)descriptorStruct;
78:
79: IOLog("DESC: ");
80: IOLog("%x (%x) ", (unsigned int)&desc->status.data, desc->status.data);
81: IOLog("%x (%x: %x %x) ", (unsigned int)&desc->control.data, desc->control.data, desc->control.reg.byteCountBuffer1, desc->control.reg.byteCountBuffer2);
82: IOLog("%x (%x) ", (unsigned int)&desc->bufferAddress1, desc->bufferAddress1);
83: IOLog("%x (%x) ", (unsigned int)&desc->bufferAddress2, desc->bufferAddress2);
84: IOLog("\n");
85:
86: }
87: #endif DEBUG
88:
89: /*
90: * Breaks up an ethernet data buffer into two physical chunks. We know that
91: * the buffer can't straddle more than two pages. If the content of paddr2 is
92: * zero this means that all of the buffer lies in one physical page. Note
93: * that we use the fact that tx and rx descriptors have the same size and
94: * same layout of relevent fields (data address and count).
95: */
96: static BOOL
97: IOUpdateDescriptorFromNetBuf(netbuf_t nb, void *desc, BOOL isReceive)
98: {
99: IOReturn result;
100: vm_address_t pageBreak;
101: unsigned int len;
102: vm_address_t vaddr;
103: unsigned int *paddr1, *paddr2;
104:
105: struct _descriptorStruct {
106: unsigned int status;
107: union {
108: struct {
109: unsigned int
110: rsvd :10,
111: byteCountBuffer2 :11,
112: byteCountBuffer1 :11;
113: } reg;
114: unsigned int data;
115: } control;
116: unsigned int bufferAddress1;
117: unsigned int bufferAddress2;
118: } *descriptorStruct;
119:
120:
121: descriptorStruct = (struct _descriptorStruct *)desc;
122: len = isReceive ? NETWORK_BUFSIZE : nb_size(nb);
123:
124: vaddr = (vm_address_t)nb_map(nb);
125: paddr1 = &descriptorStruct->bufferAddress1;
126: paddr2 = &descriptorStruct->bufferAddress2;
127:
128: /* Assume contiguity */
129: *paddr2 = 0;
130: descriptorStruct->control.reg.byteCountBuffer2 = 0;
131: descriptorStruct->control.reg.byteCountBuffer1 = len;
132:
133: result = IOPhysicalFromVirtual(IOVmTaskSelf(), vaddr, paddr1);
134: if (result != IO_R_SUCCESS) {
135: return NO;
136: }
137:
138: /*
139: * Now check if this memory block crosses a page boundary.
140: */
141: if (trunc_page(vaddr) == trunc_page(vaddr+len)) {
142: return YES;
143: }
144:
145: /* Nice try... */
146: pageBreak = round_page(vaddr);
147: descriptorStruct->control.reg.byteCountBuffer1 = pageBreak - vaddr;
148: descriptorStruct->control.reg.byteCountBuffer2 = len - (pageBreak - vaddr);
149:
150: result = IOPhysicalFromVirtual(IOVmTaskSelf(), pageBreak, paddr2);
151: if (result != IO_R_SUCCESS) {
152: return NO;
153: }
154:
155: return YES;
156: }
157:
158:
159: @implementation DECchip2104x (Private)
160:
161: /*
162: * Private functions
163: */
164: - (BOOL)_allocateMemory
165: {
166: int i;
167: IOReturn result;
168:
169: //kprintf("[DECchip2104x _allocateMemory]\n");
170:
171: memorySize = sizeof(rxDescriptorStruct) * DEC_21X40_RX_RING_LENGTH
172: + sizeof(txDescriptorStruct) * DEC_21X40_TX_RING_LENGTH
173: + DEC_21X40_DESCRIPTOR_ALIGNMENT * 2
174: + sizeof(setupBuffer_t) + DEC_21X40_DESCRIPTOR_ALIGNMENT;
175: if (memorySize > PAGE_SIZE) {
176: IOLog("%s: 1 page limit exceeded for descriptor memory\n",[self name]);
177: return NO;
178: }
179:
180: /*
181: * We need one page of contiguous memory.
182: */
183: result = kmem_alloc_wired(kernel_map,(vm_offset_t *)&memoryPtr,memorySize);
184: if (result != KERN_SUCCESS) {
185: IOLog ("%s: can't allocate 0x%x bytes of memory\n",
186: [self name], memorySize);
187: return NO;
188: }
189:
190: rxRing = (rxDescriptorStruct *)memoryPtr;
191: if (!IOIsAligned(rxRing, DEC_21X40_DESCRIPTOR_ALIGNMENT))
192: rxRing = IOAlign(rxDescriptorStruct *, rxRing,
193: DEC_21X40_DESCRIPTOR_ALIGNMENT);
194: for (i = 0 ; i < DEC_21X40_RX_RING_LENGTH ; i++) {
195: bzero((void *)&rxRing[i], sizeof(rxDescriptorStruct));
196: rxNetbuf[i] = NULL;
197: }
198:
199: txRing = (txDescriptorStruct *)(rxRing + DEC_21X40_RX_RING_LENGTH);
200: if (!IOIsAligned(txRing, DEC_21X40_DESCRIPTOR_ALIGNMENT))
201: txRing = IOAlign(txDescriptorStruct *, txRing,
202: DEC_21X40_DESCRIPTOR_ALIGNMENT);
203: for (i = 0 ; i < DEC_21X40_TX_RING_LENGTH ; i++) {
204: bzero((void *)&txRing[i], sizeof(txDescriptorStruct));
205: txNetbuf[i] = NULL;
206: }
207:
208: setupBuffer = (setupBuffer_t *)(txRing + DEC_21X40_TX_RING_LENGTH);
209: if (!IOIsAligned(setupBuffer, DEC_21X40_DESCRIPTOR_ALIGNMENT))
210: setupBuffer = IOAlign(setupBuffer_t *,
211: setupBuffer, DEC_21X40_DESCRIPTOR_ALIGNMENT);
212: result = IOPhysicalFromVirtual(IOVmTaskSelf(),
213: (vm_address_t)setupBuffer, (unsigned *)&setupBufferPhysical);
214: if (result != IO_R_SUCCESS) {
215: IOLog("%s: Invalid shared memory address\n", [self name]);
216: return NO;
217: }
218:
219: return YES;
220: }
221:
222: #ifdef DEBUG
223: - (void)_dumpRegisters
224: {
225: int i;
226:
227: return;
228: IOLog("%s: Regs: ", [self name]);
229: for (i = 0; i <= 15; i++) {
230: IOLog("%02d: %x ", i, readCsr(ioBase, 8*i));
231: }
232: IOLog("\n");
233: }
234: #endif DEBUG
235:
236: #ifdef DEBUG
237: - (void)_dumpDescriptor:(void *)ds
238: {
239: txDescriptorStruct *desc = (txDescriptorStruct *)ds;
240:
241: IOLog("%s: Desc: ", [self name]);
242: IOLog("%x ", *(unsigned int *)&desc->status);
243: IOLog("%x ", *(unsigned int *)&desc->control);
244: IOLog("%x ", *(unsigned int *)&desc->bufferAddress1);
245: IOLog("%x ", *(unsigned int *)&desc->bufferAddress2);
246: IOLog("\n");
247: }
248: #endif DEBUG
249:
250: - (BOOL)_initTxRing
251: {
252: unsigned int i;
253:
254: //kprintf("[DECchip2104x _initTxRing]\n");
255:
256: for (i = 0; i < DEC_21X40_TX_RING_LENGTH; i++) {
257: bzero((void *)&txRing[i], sizeof(txDescriptorStruct));
258: txRing[i].status.reg.own = DEC_21X40_DESC_OWNED_BY_HOST;
259: if (txNetbuf[i]) {
260: nb_free(txNetbuf[i]);
261: txNetbuf[i] = NULL;
262: }
263: }
264: txRing[DEC_21X40_TX_RING_LENGTH-1].control.reg.ter = YES;
265:
266: txPutIndex = 0;
267: txDoneIndex = 0;
268: txNumFree = DEC_21X40_TX_RING_LENGTH;
269: txIntCount = 0;
270:
271: /* Init the transmit queue. */
272: if (transmitQueue) {
273: [transmitQueue free];
274: }
275: transmitQueue = [[IONetbufQueue alloc]
276: initWithMaxCount:TRANSMIT_QUEUE_SIZE];
277: if (!transmitQueue) {
278: IOPanic("_initTxRing");
279: }
280:
281: return YES;
282: }
283:
284: - (BOOL)_initRxRing
285: {
286: int i;
287: BOOL status;
288:
289: //kprintf("[DECchip2104x _initRxRing]\n");
290:
291: for (i = 0; i < DEC_21X40_RX_RING_LENGTH; i++) {
292: bzero((void *)&rxRing[i], sizeof(rxDescriptorStruct));
293: rxRing[i].status.reg.own = DEC_21X40_DESC_OWNED_BY_HOST;
294: if (rxNetbuf[i] == NULL) {
295: rxNetbuf[i] = [self allocateNetbuf];
296: if (rxNetbuf[i] == NULL) {
297: IOPanic("allocateNetbuf returned NULL in _initRxRing");
298: }
299: }
300: status = IOUpdateDescriptorFromNetBuf(rxNetbuf[i],
301: (void *)&rxRing[i], YES);
302: if (status == NO)
303: IOPanic("_initRxRing");
304: rxRing[i].status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
305: }
306:
307: rxRing[DEC_21X40_RX_RING_LENGTH-1].control.reg.rer = YES;
308:
309: rxDoneIndex = 0;
310:
311: return YES;
312: }
313:
314:
315: - (BOOL) _initChip
316: {
317:
318: //kprintf("[DECchip2104x _initChip]\n");
319:
320: [self _initRegisters];
321: [self _startTransmit];
322:
323: /*
324: * Set up station, broadcast, and multicast addresses
325: */
326: if (![self _setAddressFiltering:YES])
327: return NO;
328:
329: [self selectInterface];
330:
331: #ifdef DEBUG
332: [self _dumpRegisters];
333: #endif DEBUG
334:
335: return YES;
336: }
337:
338: - (void)_resetChip
339: {
340: csrRegUnion reg;
341:
342: //kprintf("[DECchip2104x _resetChip]\n");
343:
344: reg.data = 0;
345: reg.csr0.swr = 1; /* reset */
346: writeCsr(ioBase, DEC_21X40_CSR0, reg.data);
347: IODelay(100);
348: reg.csr0.swr = 0; /* deassert */
349: writeCsr(ioBase, DEC_21X40_CSR0, reg.data);
350:
351: IOSleep(1); /* >= 100 PCI bus cycles */
352: }
353:
354: - (void)_startTransmit
355: {
356:
357: //kprintf("[DECchip2104x _startTransmit]\n");
358:
359: operationMode.csr6.st = YES;
360: writeCsr(ioBase, DEC_21X40_CSR6, operationMode.data);
361: }
362:
363: - (void)_startReceive
364: {
365:
366: //kprintf("[DECchip2104x _startReceive]\n");
367:
368: operationMode.csr6.sr = YES;
369: writeCsr(ioBase, DEC_21X40_CSR6, operationMode.data);
370: }
371:
372: - (void)_initRegisters
373: {
374: IOReturn result;
375: csrRegUnion reg;
376:
377: unsigned int paddr;
378:
379: //kprintf("[DECchip2104x _initRegisters]\n");
380:
381: [self _resetChip];
382:
383: reg.data = 0;
384: reg.csr0.dbo = 1; /* Big Endian Descriptors */
385: // reg.csr0.ble = 1; /* Big Endian Buffers */
386: reg.csr0.pbl = 16; /* errata: don't set to 0 or 32 */
387: reg.csr0.cal = 1; /* depends upon NETWORK_BUFALIGNMENT */
388: writeCsr(ioBase, DEC_21X40_CSR0, reg.data); /* bus mode */
389:
390: result = IOPhysicalFromVirtual(IOVmTaskSelf(),
391: (vm_address_t)rxRing, (unsigned int *)&paddr);
392: if (result != IO_R_SUCCESS) {
393: IOLog("%s: Invalid shared memory address\n", [self name]);
394: return;
395: }
396: reg.data = 0;
397: reg.csr3.rdlba = (unsigned int)paddr;
398: writeCsr(ioBase, DEC_21X40_CSR3, reg.data); /* receive list base */
399:
400: result = IOPhysicalFromVirtual(IOVmTaskSelf(),
401: (vm_address_t)txRing, (unsigned int *)&paddr);
402: if (result != IO_R_SUCCESS) {
403: IOLog("%s: Invalid shared memory address\n", [self name]);
404: return;
405: }
406: reg.data = 0;
407: reg.csr4.tdlba = (unsigned int)paddr;
408: writeCsr(ioBase, DEC_21X40_CSR4, reg.data); /* transmit list base */
409:
410: reg.data = 0; /* FIXME -- choose appropriate values */
411: writeCsr(ioBase, DEC_21X40_CSR6, reg.data); /* operations mode */
412: operationMode.data = reg.data;
413:
414: reg.data = 0;
415: reg.csr7.tim = reg.csr7.rim = reg.csr7.tjm = 1;
416: reg.csr7.nim = 1;
417: #ifdef DEBUG
418: reg.csr7.tim = reg.csr7.tsm = reg.csr7.tum = reg.csr7.tjm = 1;
419: reg.csr7.unm = reg.csr7.rim = reg.csr7.rum = 1;
420: reg.csr7.atm = 1;
421: reg.csr7.lfm = reg.csr7.sem = reg.csr7.aim = 1;
422: #endif DEBUG
423: interruptMask.data = reg.data;
424:
425: writeCsr(ioBase, DEC_21X40_CSR11, 0); /* no full duplex */
426: }
427:
428: - (void)_transmitPacket:(netbuf_t)packet
429: {
430: csrRegUnion reg;
431: txDescriptorStruct *desc;
432: BOOL status;
433:
434: //kprintf("[DECchip2104x _transmitPacket]\n");
435:
436: [self performLoopback:packet];
437:
438: [self reserveDebuggerLock];
439:
440: if (txNumFree == 0) {
441: [self releaseDebuggerLock];
442: nb_free(packet);
443: return;
444: }
445:
446: desc = &txRing[txPutIndex];
447: txNetbuf[txPutIndex] = packet;
448:
449: if (desc->control.reg.ter == 1) {
450: desc->control.data = 0;
451: desc->control.reg.ter = 1;
452: }
453: else
454: desc->control.data = 0;
455:
456: status = IOUpdateDescriptorFromNetBuf(packet, (void *)desc, NO);
457: if (status == NO) {
458: [self releaseDebuggerLock];
459: IOLog("%s: _transmitPacket: IOUpdateDescriptorFromNetBuf failed\n",
460: [self name]);
461: nb_free(packet); /* this is the best we can do here */
462: return;
463: }
464:
465: desc->control.reg.fs = YES;
466: desc->control.reg.ls = YES;
467: if (++txIntCount == (DEC_21X40_TX_RING_LENGTH / 2)) {
468: desc->control.reg.ic = YES;
469: txIntCount = 0;
470: }
471: else
472: desc->control.reg.ic = NO;
473:
474: desc->status.data = 0;
475: desc->status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
476:
477: // txPutIndex = (txPutIndex + 1) % DEC_21X40_TX_RING_LENGTH;
478: if (++txPutIndex == DEC_21X40_TX_RING_LENGTH)
479: txPutIndex = 0;
480: --txNumFree;
481:
482: /*
483: * Make the chip poll immediately.
484: */
485: reg.data = 0;
486: reg.csr1.tpd = YES;
487: writeCsr(ioBase, DEC_21X40_CSR1, reg.data);
488:
489: [self releaseDebuggerLock];
490:
491: return;
492: }
493:
494: /*
495: * Method: receivePacket
496: *
497: * Purpose:
498: * Part of kerneldebugger protocol.
499: */
500: - (void)receivePacket:(void *)pkt length:(unsigned int *)pkt_len
501: timeout:(unsigned int)timeout
502: {
503: *pkt_len = 0;
504: timeout *= 1000;
505:
506: if (resetAndEnabled == NO)
507: return;
508:
509: while (1) {
510: if (rxRing[rxDoneIndex].status.reg.own
511: == DEC_21X40_DESC_OWNED_BY_HOST) {
512: rxDescriptorStruct * rds;
513:
514: rds = &rxRing[rxDoneIndex];
515: if (rds->status.reg.es
516: || (!rds->status.reg.fs || !rds->status.reg.ls)
517: || (rds->status.reg.fl < ETHERMINPACKET)) {
518: rxRing[rxDoneIndex].status.reg.own
519: = DEC_21X40_DESC_OWNED_BY_CTRL;
520: // rxDoneIndex = (rxDoneIndex + 1) % DEC_21X40_RX_RING_LENGTH;
521: if (++rxDoneIndex == DEC_21X40_RX_RING_LENGTH)
522: rxDoneIndex = 0;
523: }
524: else
525: break;
526: }
527: else {
528: if ((int)timeout <= 0)
529: return;
530: IODelay(50);
531: timeout -= 50;
532: }
533: }
534: {
535: rxDescriptorStruct * rds;
536:
537: rds = &rxRing[rxDoneIndex];
538: *pkt_len = rds->status.reg.fl - ETHERCRC;
539: bcopy(nb_map(rxNetbuf[rxDoneIndex]), pkt, *pkt_len);
540:
541: rds->status.data = 0;
542: rds->status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
543: // rxDoneIndex = (rxDoneIndex + 1) % DEC_21X40_RX_RING_LENGTH;
544: if (++rxDoneIndex == DEC_21X40_RX_RING_LENGTH)
545: rxDoneIndex = 0;
546: }
547: return;
548: }
549: /*
550: * Method: sendPacket
551: *
552: * Purpose:
553: * Part of kerneldebugger protocol.
554: */
555: - (void)sendPacket:(void *)pkt length:(unsigned int)pkt_len
556: {
557: int size;
558: volatile txDescriptorStruct * desc;
559: csrRegUnion reg;
560: BOOL status;
561:
562: if (resetAndEnabled == NO)
563: return; /* can't transmit right now */
564:
565: [self _transmitInterruptOccurred];
566:
567: if (txNumFree == 0) {
568: IOLog("%s: _sendPacket: No free tx descriptors\n", [self name]);
569: return; /* can't transmit right now */
570: }
571:
572: desc = &txRing[txPutIndex];
573: txNetbuf[txPutIndex] = NULL;
574:
575: bcopy(pkt, nb_map(KDB_txBuf), pkt_len);
576: size = nb_size(KDB_txBuf);
577: nb_shrink_bot(KDB_txBuf, size - pkt_len);
578:
579: if (desc->control.reg.ter == 1) {
580: desc->control.data = 0;
581: desc->control.reg.ter = 1;
582: }
583: else
584: desc->control.data = 0;
585:
586: status = IOUpdateDescriptorFromNetBuf(KDB_txBuf, (void *)desc, NO);
587: if (status == NO) {
588: IOLog("%s: _sendPacket: IOUpdateDescriptorFromNetBuf failed\n",
589: [self name]);
590: return;
591: }
592:
593: desc->control.reg.fs = YES;
594: desc->control.reg.ls = YES;
595: desc->control.reg.ic = NO;
596: desc->status.data = 0;
597: desc->status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
598:
599: // txPutIndex = (txPutIndex + 1) % DEC_21X40_TX_RING_LENGTH;
600: if (++txPutIndex == DEC_21X40_TX_RING_LENGTH)
601: txPutIndex = 0;
602: --txNumFree;
603:
604: /*
605: * Make the chip poll immediately.
606: */
607: reg.data = 0;
608: reg.csr1.tpd = YES;
609: writeCsr(ioBase, DEC_21X40_CSR1, reg.data);
610:
611: { /* poll for completion */
612: int i;
613: for (i = 0;
614: i < 10000 && desc->status.reg.own == DEC_21X40_DESC_OWNED_BY_CTRL;
615: i++) {
616: IODelay(500);
617: }
618: }
619: if (desc->status.reg.own == DEC_21X40_DESC_OWNED_BY_CTRL)
620: IOLog("%s: _sendPacket: polling timed out\n", [self name]);
621:
622: /* restore the actual size of the buffer */
623: nb_grow_bot(KDB_txBuf, size - pkt_len);
624:
625: return;
626: }
627:
628: - (BOOL)_receiveInterruptOccurred
629: {
630: netbuf_t packet;
631: BOOL passPacketUp;
632: rxDescriptorStruct * rds;
633: unsigned int receivedFrameSize;
634: BOOL status;
635:
636: //kprintf("[DECchip2104x _receiveInterruptOccurred]\n");
637:
638: [self reserveDebuggerLock];
639:
640: while (rxRing[rxDoneIndex].status.reg.own
641: == DEC_21X40_DESC_OWNED_BY_HOST) {
642: passPacketUp = NO;
643: rds = &rxRing[rxDoneIndex];
644: receivedFrameSize = rds->status.reg.fl - ETHERCRC;
645:
646: /*
647: * Bad packet. Just leave the netbuf in place.
648: */
649: if (rds->status.reg.es
650: || (!rds->status.reg.fs || !rds->status.reg.ls)
651: || (receivedFrameSize < (ETHERMINPACKET - ETHERCRC))) {
652: [networkInterface incrementInputErrors];
653: rxRing[rxDoneIndex].status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
654: // rxDoneIndex = (rxDoneIndex + 1) % DEC_21X40_RX_RING_LENGTH;
655: if (++rxDoneIndex == DEC_21X40_RX_RING_LENGTH)
656: rxDoneIndex = 0;
657: continue;
658: }
659:
660: /* Toss packets not in our multicast address-space. */
661: packet = rxNetbuf[rxDoneIndex];
662: if (isPromiscuous
663: || rds->status.reg.mf == NO
664: || [super isUnwantedMulticastPacket:
665: (ether_header_t *)nb_map(packet)] == NO) {
666: netbuf_t newPacket;
667:
668: newPacket = [self allocateNetbuf];
669: if (newPacket != NULL) {
670: rxNetbuf[rxDoneIndex] = newPacket;
671: passPacketUp = YES;
672: status =
673: IOUpdateDescriptorFromNetBuf(rxNetbuf[rxDoneIndex],
674: (void *)&rxRing[rxDoneIndex],
675: YES);
676: if (status == NO) {
677: IOPanic("DECchip21040: IOUpdateDescriptorFromNetBuf\n");
678: }
679: /* Adjust to size received */
680: nb_shrink_bot(packet, nb_size(packet) - receivedFrameSize);
681: }
682: }
683: rds->status.data = 0;
684: rds->status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
685:
686: // rxDoneIndex = (rxDoneIndex + 1) % DEC_21X40_RX_RING_LENGTH;
687: if (++rxDoneIndex == DEC_21X40_RX_RING_LENGTH)
688: rxDoneIndex = 0;
689: if (passPacketUp) {
690: passPacketUp = NO;
691: [self releaseDebuggerLock];
692: [networkInterface handleInputPacket:packet extra:0];
693: [self reserveDebuggerLock];
694: }
695: }
696:
697: [self releaseDebuggerLock];
698:
699: return YES;
700: }
701:
702: - (BOOL)_transmitInterruptOccurred
703: {
704: txDescriptorStruct *tds;
705:
706: //kprintf("[DECchip2104x _transmitInterruptOccurred]\n");
707:
708: while (txNumFree < DEC_21X40_TX_RING_LENGTH) {
709: tds = &txRing[txDoneIndex];
710: if (tds->status.reg.own == DEC_21X40_DESC_OWNED_BY_CTRL)
711: break;
712:
713: if (tds->control.reg.set == 1) {
714: //IOLog("TX interrupt: Ignoring set up packet\n");
715: // txDoneIndex = (txDoneIndex + 1) % DEC_21X40_TX_RING_LENGTH;
716: if (++txDoneIndex == DEC_21X40_TX_RING_LENGTH)
717: txDoneIndex = 0;
718: ++txNumFree;
719: continue;
720: }
721:
722: if (tds->status.reg.uf || tds->status.reg.ec
723: || tds->status.reg.lc || tds->status.reg.nc
724: || tds->status.reg.to)
725: [networkInterface incrementOutputErrors];
726: else
727: [networkInterface incrementOutputPackets];
728:
729: if (tds->status.reg.ec)
730: [networkInterface incrementCollisionsBy:16];
731: else if (tds->status.reg.cc)
732: [networkInterface incrementCollisionsBy:tds->status.reg.cc];
733: if (tds->status.reg.lc && !tds->status.reg.uf)
734: [networkInterface incrementCollisions];
735:
736: if (txNetbuf[txDoneIndex] != NULL) {
737: nb_free(txNetbuf[txDoneIndex]);
738: txNetbuf[txDoneIndex] = NULL;
739: }
740: // txDoneIndex = (txDoneIndex + 1) % DEC_21X40_TX_RING_LENGTH;
741: if (++txDoneIndex == DEC_21X40_TX_RING_LENGTH)
742: txDoneIndex = 0;
743: ++txNumFree;
744: }
745:
746: return YES;
747: }
748:
749: #define DEC_21X40_SETUP_TIMEOUT 10000
750:
751: - (BOOL)_loadSetupFilter:(BOOL)pollingMode
752: {
753: txDescriptorStruct *setupDescriptor;
754: unsigned int time = DEC_21X40_SETUP_TIMEOUT;
755: csrRegUnion reg;
756:
757: //kprintf("[DECchip2104x _loadSetupFilter]\n");
758:
759: /*
760: * Make sure that we have a descriptor for setup frame
761: */
762: if (txNumFree == 0)
763: return NO;
764:
765: setupDescriptor = &txRing[txPutIndex];
766: // txPutIndex = (txPutIndex + 1) % DEC_21X40_TX_RING_LENGTH;
767: if (++txPutIndex == DEC_21X40_TX_RING_LENGTH)
768: txPutIndex = 0;
769: --txNumFree;
770:
771: /*
772: * Initialize the Setup descriptor
773: */
774: if (setupDescriptor->control.reg.ter == YES) {
775: setupDescriptor->control.data = 0;
776: setupDescriptor->control.reg.ter = YES;
777: } else {
778: setupDescriptor->control.data = 0;
779: }
780:
781: setupDescriptor->control.reg.set = YES;
782: setupDescriptor->control.reg.ic = YES;
783: setupDescriptor->control.reg.byteCountBuffer1 =
784: sizeof(setupBuffer_t);
785: setupDescriptor->control.reg.byteCountBuffer2 = 0;
786:
787: setupDescriptor->bufferAddress1 = setupBufferPhysical;
788: setupDescriptor->bufferAddress2 = 0;
789:
790: setupDescriptor->status.data = 0;
791: setupDescriptor->status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
792:
793: /* tell the chip about this setup command */
794: reg.data = 0;
795: reg.csr1.tpd = YES;
796: writeCsr(ioBase, DEC_21X40_CSR1, reg.data);
797:
798: if (pollingMode) {
799: while (time--) {
800: IODelay(5);
801: reg.data = readCsr(ioBase, DEC_21X40_CSR5);
802: if (reg.csr5.tu) {
803: writeCsr(ioBase, DEC_21X40_CSR5, reg.data);
804: break;
805: }
806: }
807:
808: // txDoneIndex = (txDoneIndex + 1) % DEC_21X40_TX_RING_LENGTH;
809: if (++txDoneIndex == DEC_21X40_TX_RING_LENGTH)
810: txDoneIndex = 0;
811: ++txNumFree;
812: }
813:
814: return YES;
815: }
816:
817: - (BOOL)_setAddressFiltering:(BOOL)pollingMode
818: {
819: int i;
820: BOOL status = YES;
821: unsigned q_count;
822: unsigned short *address;
823:
824: //kprintf("[DECchip2104x _setAddressFiltering]\n");
825:
826: /*
827: * Copy station address into the first entry. Note that the
828: * upper 2 bytes of all longwords in the setup frame are don't
829: * cares for perfect filtering.
830: */
831: address = (unsigned short *)&myAddress;
832: for (i = 0 ; i < 3; i++) {
833: unsigned short addr = (unsigned short)*address++;
834: setupBuffer->physicalAddress[0][i] = (addr << 16);
835: }
836:
837: /*
838: * Load the broadcast address in the second entry
839: */
840: for (i = 0 ; i < 3; i++) {
841: setupBuffer->physicalAddress[1][i] = 0xffffffff;
842: }
843:
844: /*
845: * Skip over the first 2 entries
846: */
847: q_count = 2;
848:
849: if (multicastEnabled) {
850: enetMulti_t *multiAddr;
851: queue_head_t *multiQueue = [super multicastQueue];
852:
853: if (!queue_empty(multiQueue)) {
854: /*
855: * Fill in the addresses
856: */
857: queue_iterate(multiQueue, multiAddr, enetMulti_t *, link) {
858: union {
859: unsigned char bytes[4];
860: unsigned long word;
861: } typeConvert;
862:
863: typeConvert.word = 0;
864:
865: for (i = 0; i < 3; i++) {
866: typeConvert.bytes[0] = multiAddr->address.ea_byte[i*2];
867: typeConvert.bytes[1] = multiAddr->address.ea_byte[i*2+1];
868: setupBuffer->physicalAddress[q_count][i] =
869: typeConvert.word;
870: }
871: if (++q_count >= DEC_21X40_SETUP_PERFECT_ENTRIES) {
872: IOLog("%s: %d multicast address limit exceeded\n",
873: [self name], DEC_21X40_SETUP_PERFECT_MCAST_ENTRIES);
874: break;
875: }
876: }
877: }
878: }
879:
880: /*
881: * Duplicate station address for remaining entries
882: */
883: for (; q_count < DEC_21X40_SETUP_PERFECT_ENTRIES; ++q_count) {
884: bcopy(setupBuffer->physicalAddress[0],
885: setupBuffer->physicalAddress[q_count],
886: 3 * sizeof (long));
887: }
888:
889: if (![self _loadSetupFilter:pollingMode])
890: status = NO;
891:
892: return status;
893: }
894:
895:
896: @end
897:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.