|
|
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: * HISTORY
29: * 11-Dec-95 Dieter Siegmund at NeXT ([email protected])
30: * Split out 21040 and 21041 into separate personalities
31: */
32:
33: #import <machdep/ppc/powermac.h>
34:
35: #import "DECchip21041.h"
36:
37: //#define DEBUG
38:
39: #import "DECchip2104xInline.h"
40:
41: #define SROM_ADDRESS_BITS "SROM Address Bits"
42: #define ENET_ADDRESS_OFFSET "Address Offset"
43:
44: static u_int8_t reverseBitOrder(u_int8_t data);
45:
46:
47: @implementation DECchip21041
48: /*
49: * Public Instance Methods
50: */
51:
52: - initFromDeviceDescription:(IODeviceDescription *)devDesc
53: {
54: IOPCIDevice *deviceDescription = (IOPCIDevice *)devDesc;
55: const char *params, *interface;
56: unsigned long PCICommandReg;
57:
58: if ([super initFromDeviceDescription:devDesc] == nil) {
59: return nil;
60: }
61:
62: #ifdef PERF
63: perfQ = perfGetQueue(OUR_PRODUCER_NAME, &ourProducerId, 0);
64: if (!perfQ)
65: IOLog("%s: perfGetQueue failed\n", OUR_PRODUCER_NAME);
66: else {
67: IOLog("%s: perf logging enabled\n", OUR_PRODUCER_NAME);
68: ev_p.len = sizeof(ev_p);
69: ev_p.producerId = ourProducerId;
70: }
71: #endif PERF
72:
73: // Set the PCI Command Register for Bus Master, Memory Access
74: // and not I/O Access.
75: [deviceDescription configReadLong:0x04 value:&PCICommandReg];
76: PCICommandReg |= (4 | 1); // Master & Memory
77: PCICommandReg &= ~2; // Not I/O
78: [deviceDescription configWriteLong:0x04 value:PCICommandReg];
79:
80: [self mapMemoryRange:0 to:(vm_address_t *)&ioBase
81: findSpace:YES cache:IO_CacheOff];
82:
83: //kprintf("ioBase = %8x\n", ioBase);
84:
85: irq = [deviceDescription interrupt];
86:
87: /* Address bits needed depends upon SROM size. */
88: params = [[deviceDescription configTable]
89: valueForStringKey: SROM_ADDRESS_BITS];
90: if ((params == NULL) || (strcmp(params, "8") != 0))
91: sromAddressBits = 6;
92: else
93: sromAddressBits = 8;
94:
95: params = [[deviceDescription configTable]
96: valueForStringKey: ENET_ADDRESS_OFFSET];
97: if (params == NULL)
98: enetAddressOffset = 20; /* DEC standard location */
99: else
100: enetAddressOffset = _atoi(params);
101:
102: /* Select network interface */
103: connector = connectorAUTO_e; /* default is auto select */
104: interface = [[deviceDescription configTable]
105: valueForStringKey: NETWORK_INTERFACE];
106: if (interface != NULL) {
107: int i;
108:
109: for (i = 0; i < NUM_CONNECTOR_TYPES; i++) {
110: if (strcmp(interface, connectorType(i)) == 0) {
111: connector = i;
112: break;
113: }
114: }
115: }
116:
117: [self getStationAddress:&myAddress];
118:
119: if ([self _allocateMemory] == NO) {
120: [self free];
121: return nil;
122: }
123:
124: isPromiscuous = NO;
125: multicastEnabled = NO;
126:
127: IOLog("DECchip21041 based adapter at port 0x%0x irq %d", ioBase, irq);
128:
129: if (connector != connectorAUTO_e) {
130: IOLog(" interface %s", interface);
131: }
132: IOLog("\n");
133:
134: if (![self resetAndEnable:NO]) {
135: [self free];
136: return nil;
137: }
138:
139: networkInterface = [super attachToNetworkWithAddress:myAddress];
140:
141: return self;
142: }
143:
144: - (void)getStationAddress:(enet_addr_t *)ea
145: {
146: int i;
147: unsigned short data;
148:
149: //_dump_srom(ioBase, sromAddressBits);
150: for (i = 0; i < sizeof(*ea)/2; i++) {
151: reset_and_select_srom(ioBase);
152: data = read_srom(ioBase, i + enetAddressOffset/2, sromAddressBits);
153:
154: // See if this is a Powerbook with combo ethernet/modem.
155: if (IsPowerStar() && HasPMU() && (powermac_io_info.io_base2)) {
156: // Hooper/Kanga Enet/modem Addr is not bit reversed
157: ea->ea_byte[2*i] = data & 0x0ff;
158: ea->ea_byte[2*i+1] = (data >> 8) & 0x0ff;
159: } else {
160: ea->ea_byte[2*i] = reverseBitOrder(data & 0x0ff);
161: ea->ea_byte[2*i+1] = reverseBitOrder((data >> 8) & 0x0ff);
162: }
163: }
164: }
165:
166: /*
167: * These are the magic values that need to be written to CSR 12, 14 and 15 to
168: * enable appropriate network interfaces. These values are from the
169: * respective hardware docs.
170: */
171: #define DEC_21041_RESET_SIA 0x0
172:
173: #if 1
174: #define DEC_21041_SIA0_10BT 0x0000ef01
175: #define DEC_21041_SIA1_10BT 0x00007f3f
176: #define DEC_21041_SIA2_10BT 0x00000048
177: #else
178: #define DEC_21041_SIA0_10BT 0x0000ef01
179: #define DEC_21041_SIA1_10BT 0x0000ff3f
180: #define DEC_21041_SIA2_10BT 0x00000008
181: #endif
182:
183: #define DEC_21041_SIA0_AUI 0x0000ef09
184: #define DEC_21041_SIA1_AUI 0x0000f73d
185: #define DEC_21041_SIA2_AUI 0x0000000e
186:
187: #define DEC_21041_SIA0_BNC 0x0000ef09
188: #define DEC_21041_SIA1_BNC 0x0000f73d
189: #define DEC_21041_SIA2_BNC 0x00000006
190:
191: - (void)_setInterface:(connector_t)netInterface
192: {
193: writeCsr(ioBase, DEC_21X40_CSR13, DEC_21041_RESET_SIA);
194: IOSleep(1);
195: switch (netInterface) {
196: case connectorTP_e:
197: writeCsr(ioBase, DEC_21X40_CSR15, DEC_21041_SIA2_10BT);
198: writeCsr(ioBase, DEC_21X40_CSR14, DEC_21041_SIA1_10BT);
199: writeCsr(ioBase, DEC_21X40_CSR13, DEC_21041_SIA0_10BT);
200: break;
201: case connectorAUI_e:
202: writeCsr(ioBase, DEC_21X40_CSR15, DEC_21041_SIA2_AUI);
203: writeCsr(ioBase, DEC_21X40_CSR14, DEC_21041_SIA1_AUI);
204: writeCsr(ioBase, DEC_21X40_CSR13, DEC_21041_SIA0_AUI);
205: break;
206: case connectorBNC_e:
207: writeCsr(ioBase, DEC_21X40_CSR15, DEC_21041_SIA2_BNC);
208: writeCsr(ioBase, DEC_21X40_CSR14, DEC_21041_SIA1_BNC);
209: writeCsr(ioBase, DEC_21X40_CSR13, DEC_21041_SIA0_BNC);
210: break;
211: default:
212: break;
213: }
214: IODelay(100);
215: connector = netInterface;
216:
217: //kprintf("CSR13 = %x CSR14 = %x CSR15 = %x\n",
218: // readCsr(ioBase, DEC_21X40_CSR13),
219: // readCsr(ioBase, DEC_21X40_CSR14),
220: // readCsr(ioBase, DEC_21X40_CSR15));
221: }
222:
223: - (void)selectInterface
224: {
225: csrRegUnion reg;
226: unsigned int time;
227:
228: //kprintf("[DECchip21041 selectInterface]\n");
229:
230: /*
231: * Auto-selection is done only once.
232: */
233: if (connector != connectorAUTO_e) {
234: [self _setInterface:connector];
235: return;
236: }
237:
238:
239: /* check for link pass interrupt using RJ-45 */
240: [self _setInterface:connectorTP_e];
241: time = 50;
242: while (--time) {
243: IOSleep(1);
244: reg.data = readCsr(ioBase, DEC_21X40_CSR5);
245: if (reg.csr5_41.lnp) {
246: IOLog("%s: detected TP port\n", [self name]);
247: return;
248: }
249: if (reg.csr5_41.lnf == 1)
250: break;
251: }
252:
253: /* check for activity on the AUI port */
254: [self _setInterface:connectorAUI_e];
255: time = 50;
256: while (--time) {
257: IOSleep(1);
258: reg.data = readCsr(ioBase, DEC_21X40_CSR5);
259: if (reg.csr5_41.lnp) {
260: IOLog("%s: detected TP port\n", [self name]);
261: [self _setInterface:connectorTP_e];
262: return;
263: }
264: reg.data = readCsr(ioBase, DEC_21X40_CSR12);
265: if (reg.csr12_41.sra)
266: break;
267: }
268: reg.data = readCsr(ioBase, DEC_21X40_CSR12);
269: if (reg.csr12_41.sra) {
270: IOLog("%s: detected AUI port\n", [self name]);
271: return;
272: }
273: /* use BNC if nothing else was sensed */
274: [self _setInterface:connectorBNC_e];
275: IOLog("%s: detected BNC port\n", [self name]);
276: return;
277: }
278:
279: @end
280:
281: static u_int8_t reverseBitOrder(u_int8_t data)
282: {
283: u_int8_t val = 0;
284: int i;
285:
286: for (i = 0; i < 8; i++) {
287: val <<= 1;
288: if (data & 1) val |= 1;
289: data >>= 1;
290: }
291: return val;
292: }
293:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.