Annotation of kernel/bsd/dev/ppc/drvDECchip21040/DECchip21041.m, revision 1.1.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.