|
|
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.