Annotation of kernel/bsd/dev/ppc/drvDECchip21040/DECchip21041.m, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.