|
|
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: * Hardware independent (relatively) code for the DECchip 2104x
29: *
30: * HISTORY
31: *
32: * 26-Apr-95 Rakesh Dubey (rdubey) at NeXT
33: * Created.
34: * 11-Oct-95 Dieter Siegmund (dieter) at NeXT
35: * Added performance hooks; changed transmit interrupt
36: * to only interrupt every N / 2 times, where N is the
37: * number of transmit descriptors. This reduces the
38: * number of interrupts taken, and the amount of CPU
39: * used by the driver.
40: * Removed timeout mechanism.
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: * Re-named 2104x.m, split out 21040 and 21041 personalities.
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:
59: //#define DEBUG
60:
61: #import "DECchip2104xInline.h"
62:
63: @implementation DECchip2104x
64:
65: /*
66: * Public Factory Methods
67: */
68:
69: + (BOOL)probe:(IOPCIDevice *)devDesc
70: {
71: DECchip2104x *dev;
72:
73: IOLog("%s: PCI Dev: %d Func: %d Bus: %d\n", [self name],
74: devDesc->deviceNum, devDesc->functionNum, devDesc->busNum);
75:
76: // Veryfy the corect number of memory ranges
77: // Range 0 is I/O Space access to CSR's
78: // Range 1 is Memory Space access to Expansion ROM
79: // Range 2 is Memory Space access to CSR's
80: if ([devDesc numMemoryRanges] != 3) {
81: IOLog("%s: Incorrect number of memory ranges -> %d\n",
82: [self name], [devDesc numMemoryRanges]);
83: return NO;
84: }
85:
86: dev = [self alloc];
87: if (dev == nil) {
88: IOLog("%s: Failed to alloc instance\n", [self name]);
89: return NO;
90: }
91:
92: return [dev initFromDeviceDescription:devDesc] != nil;
93: }
94:
95: /*
96: * Public Instance Methods
97: */
98: - initFromDeviceDescription:(IODeviceDescription *)devDesc
99: {
100: if ([super initFromDeviceDescription:devDesc] == nil) {
101: [self free];
102: return nil;
103: }
104: KDB_txBuf = [self allocateNetbuf];
105: if (KDB_txBuf == NULL) {
106: IOLog("%s: couldn't allocate KDB netbuf\n", [self name]);
107: [self free];
108: return nil;
109: }
110: resetAndEnabled = NO;
111: return self;
112: }
113:
114: - free
115: {
116: int i;
117:
118: [self clearTimeout];
119:
120: [self _resetChip];
121:
122: if (networkInterface)
123: [networkInterface free];
124:
125: for (i = 0; i < DEC_21X40_RX_RING_LENGTH; i++)
126: if (rxNetbuf[i])
127: nb_free(rxNetbuf[i]);
128: for (i = 0; i < DEC_21X40_TX_RING_LENGTH; i++)
129: if (txNetbuf[i])
130: nb_free(txNetbuf[i]);
131:
132:
133: // if (memoryPtr) {
134: // IOFree(memoryPtr, memorySize);
135: // }
136: // [self enableAllInterrupts];
137:
138: return [super free];
139: }
140:
141: - (void) enableAdapterInterrupts
142: {
143:
144: //kprintf("[DECchip2104x enableAdapterInterrupts]\n");
145:
146: writeCsr(ioBase, DEC_21X40_CSR7, interruptMask.data);
147: }
148:
149: - (void) disableAdapterInterrupts
150: {
151:
152: //kprintf("[DECchip2104x disableAdapterInterrupts]\n");
153:
154: writeCsr(ioBase, DEC_21X40_CSR7, 0);
155: }
156:
157: - (BOOL)resetAndEnable:(BOOL)enable
158: {
159:
160: //kprintf("[DECchip2104x resetAndEnable]\n");
161:
162: resetAndEnabled = NO;
163: [self clearTimeout];
164: [self disableAdapterInterrupts];
165:
166: [self _resetChip];
167:
168: if (enable) {
169:
170: if (![self _initRxRing] || ![self _initTxRing]) {
171: return NO;
172: }
173:
174: if ([self _initChip] == NO) {
175: [self setRunning:NO];
176: return NO;
177: }
178:
179: [self _startTransmit];
180: [self _startReceive];
181:
182: if ([self enableAllInterrupts] != IO_R_SUCCESS) {
183: [self setRunning:NO];
184: return NO;
185: }
186: [self enableAdapterInterrupts];
187: }
188:
189: [self setRunning:enable];
190:
191: resetAndEnabled = YES;
192: return YES;
193: }
194:
195:
196: - (void)interruptOccurred
197: {
198: csrRegUnion interruptReg;
199:
200: //kprintf("[DECchip2104x interruptOccurred]\n");
201:
202: #ifdef PERF
203: if (perfQ) {
204: ev_p.eventId = PERF_INTR_ENTER_ID;
205: perfEvent(perfQ, &ev_p);
206: }
207: #endif PERF
208:
209: while (1) {
210:
211: [self reserveDebuggerLock];
212: interruptReg.data = readCsr(ioBase, DEC_21X40_CSR5);
213: writeCsr(ioBase, DEC_21X40_CSR5, interruptReg.data);
214: [self releaseDebuggerLock];
215: #ifdef DEBUG
216: IOLog("%s: interruptOccurred: status %x\n", [self name],
217: interruptReg.data);
218: #endif DEBUG
219:
220: if (!interruptReg.csr5.ti && !interruptReg.csr5.ri &&
221: !interruptReg.csr5.tjt) {
222: #ifdef DEBUG
223: IOLog("%s: BOGUS interrupt: status %x\n", [self name],
224: interruptReg.data);
225: #endif DEBUG
226: break;
227: }
228:
229: if (interruptReg.csr5.ri) {
230: [self _receiveInterruptOccurred];
231: }
232: if (interruptReg.csr5.ti) {
233: [self reserveDebuggerLock];
234: [self _transmitInterruptOccurred];
235: [self releaseDebuggerLock];
236: [self serviceTransmitQueue];
237: }
238: if (interruptReg.csr5.tjt) {
239: //[self _jabberInterruptOccurred];
240: }
241: }
242: [self enableAllInterrupts];
243: #ifdef PERF
244: if (perfQ) {
245: ev_p.eventId = PERF_INTR_EXIT_ID;
246: perfEvent(perfQ, &ev_p);
247: }
248: #endif PERF
249: }
250:
251: - (void) serviceTransmitQueue
252: {
253: netbuf_t packet;
254:
255: //kprintf("[DECchip2104x serviceTransmitQueue]\n");
256:
257:
258: while (txNumFree && [transmitQueue count] > 0
259: && (packet = [transmitQueue dequeue]))
260: [self _transmitPacket:packet];
261: }
262:
263: - (void)transmit:(netbuf_t)pkt
264: {
265:
266: //kprintf("[DECchip2104x transmit]\n");
267:
268: if (!pkt) {
269: IOLog("%s: transmit: received NULL netbuf\n", [self name]);
270: return;
271: }
272:
273: if (![self isRunning]) {
274: nb_free(pkt);
275: return;
276: }
277:
278: [self reserveDebuggerLock];
279: [self _transmitInterruptOccurred]; /* check for tx completions */
280: [self releaseDebuggerLock];
281:
282: /*
283: * Queue the packet if we're out of transmit descriptors
284: */
285: [self serviceTransmitQueue];
286: if (txNumFree == 0 || [transmitQueue count] > 0)
287: [transmitQueue enqueue:pkt];
288: else
289: [self _transmitPacket:pkt];
290:
291: }
292:
293: - (int) transmitQueueSize
294: {
295: //kprintf("[DECchip2104x transmitQueueSize]\n");
296:
297:
298: return (TRANSMIT_QUEUE_SIZE);
299: }
300:
301: - (int) transmitQueueCount
302: {
303: //kprintf("[DECchip2104x transmitQueueCount]\n");
304:
305:
306: return ([transmitQueue count]);
307: }
308:
309: - (int) pendingTransmitCount
310: {
311:
312: //kprintf("[DECchip2104x pendingTransmitCount]\n");
313:
314: return ([transmitQueue count] + (DEC_21X40_TX_RING_LENGTH - txNumFree));
315: }
316:
317: - (void)timeoutOccurred
318: {
319: //kprintf("[DECchip2104x timeoutOccurred]\n");
320:
321: #ifdef PERF
322: if (perfQ) {
323: ev_p.eventId = PERF_INTR_ENTER_ID;
324: perfEvent(perfQ, &ev_p);
325: }
326: #endif PERF
327:
328: #ifdef DEBUG
329: IOLog("tx timeout: txPutIndex=%d, txDoneIndex=%d, txNumFree=%d\n",
330: txPutIndex, txDoneIndex, txNumFree);
331: #endif DEBUG
332:
333: if ([self isRunning]) {
334: [self reserveDebuggerLock];
335: [self _transmitInterruptOccurred];
336: [self releaseDebuggerLock];
337: [self serviceTransmitQueue];
338: }
339: #ifdef PERF
340: if (perfQ) {
341: ev_p.eventId = PERF_INTR_EXIT_ID;
342: perfEvent(perfQ, &ev_p);
343: }
344: #endif PERF
345: }
346:
347: - (netbuf_t)allocateNetbuf
348: {
349: netbuf_t packet;
350: unsigned int packetAlignment;
351:
352: //kprintf("[DECchip2104x allocateNetbuf]\n");
353:
354: packet = nb_alloc(NETWORK_BUFSIZE + NETWORK_BUFALIGNMENT);
355: if (packet) {
356: packetAlignment =
357: (unsigned)nb_map(packet) & (NETWORK_BUFALIGNMENT - 1);
358: if (packetAlignment)
359: nb_shrink_top(packet, NETWORK_BUFALIGNMENT - packetAlignment);
360: nb_shrink_bot(packet, nb_size(packet) - ETHERMAXPACKET);
361: }
362: #ifdef DEBUG
363: else {
364: IOLog("%s: nb_alloc() returned NULL\n", [self name]);
365: // IOBreakToDebugger();
366: }
367: #endif DEBUG
368:
369: return packet;
370: }
371:
372: - (BOOL)enablePromiscuousMode
373: {
374: csrRegUnion reg;
375:
376: //kprintf("[DECchip2104x enablePromiscuousMode]\n");
377:
378: isPromiscuous = YES;
379:
380: [self reserveDebuggerLock];
381: reg.data = readCsr(ioBase, DEC_21X40_CSR6);
382: reg.csr6.pr = 1;
383: writeCsr(ioBase, DEC_21X40_CSR6, reg.data);
384: [self releaseDebuggerLock];
385:
386: return YES;
387: }
388:
389: - (void)disablePromiscuousMode
390: {
391: csrRegUnion reg;
392:
393: //kprintf("[DECchip2104x disablePromiscuousMode]\n");
394:
395: isPromiscuous = NO;
396:
397: [self reserveDebuggerLock];
398: reg.data = readCsr(ioBase, DEC_21X40_CSR6);
399: reg.csr6.pr = 0;
400: writeCsr(ioBase, DEC_21X40_CSR6, reg.data);
401: [self releaseDebuggerLock];
402:
403: return;
404: }
405:
406: - (BOOL)enableMulticastMode
407: {
408:
409: //kprintf("[DECchip2104x enableMulticastMode]\n");
410:
411: multicastEnabled = YES;
412: return YES;
413: }
414:
415: - (void)disableMulticastMode
416: {
417:
418: //kprintf("[DECchip2104x disableMulticastMode]\n");
419:
420: /*
421: * Clear out any current addresses
422: */
423: if (multicastEnabled) {
424: [self reserveDebuggerLock];
425: if (![self _setAddressFiltering:NO])
426: IOLog("%s: disable multicast mode failed\n",[self name]);
427: [self releaseDebuggerLock];
428: }
429: multicastEnabled = NO;
430: }
431:
432: - (void)addMulticastAddress:(enet_addr_t *)addr
433: {
434:
435: //kprintf("[DECchip2104x addMulticastAddress: %x:%x:%x:%x:%x:%x]\n",
436: // addr->ea_byte[0],addr->ea_byte[1],addr->ea_byte[2],
437: // addr->ea_byte[3],addr->ea_byte[4],addr->ea_byte[5]);
438:
439: multicastEnabled = YES;
440: [self reserveDebuggerLock];
441: if (![self _setAddressFiltering:NO])
442: IOLog("%s: add multicast address failed\n",[self name]);
443: [self releaseDebuggerLock];
444: }
445:
446: - (void)removeMulticastAddress:(enet_addr_t *)addr
447: {
448:
449: //kprintf("[DECchip2104x removeMulticastAddress]\n");
450:
451: [self reserveDebuggerLock];
452: if (![self _setAddressFiltering:NO])
453: IOLog("%s: remove multicast address failed\n",[self name]);
454: [self releaseDebuggerLock];
455: }
456:
457: /*
458: * Power management methods.
459: */
460: - (IOReturn)getPowerState:(PMPowerState *)state_p
461: {
462: return IO_R_UNSUPPORTED;
463: }
464:
465: - (IOReturn)setPowerState:(PMPowerState)state
466: {
467: if (state == PM_OFF) {
468: resetAndEnabled = NO;
469: [self _resetChip];
470: return IO_R_SUCCESS;
471: }
472: return IO_R_UNSUPPORTED;
473: }
474:
475: - (IOReturn)getPowerManagement:(PMPowerManagementState *)state_p
476: {
477: return IO_R_UNSUPPORTED;
478: }
479:
480: - (IOReturn)setPowerManagement:(PMPowerManagementState)state
481: {
482: return IO_R_UNSUPPORTED;
483: }
484:
485: - (void)getStationAddress:(enet_addr_t *)ea
486: {
487:
488: //kprintf("[DECchip2104x getStationAddress]\n");
489:
490: return;
491: }
492:
493: - (void)selectInterface
494: {
495: //kprintf("[DECchip2104x selectInterface]\n");
496:
497: return;
498: }
499:
500:
501: @end
502:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.