Annotation of kernel/bsd/dev/ppc/drvDECchip21040/DECchip2104xPrivate.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:  * Implementation for hardware dependent (relatively) code 
                     29:  * for the DECchip 21040 and 21041. 
                     30:  *
                     31:  * HISTORY
                     32:  *
                     33:  * 26-Apr-95   Rakesh Dubey (rdubey) at NeXT 
                     34:  *     Created.
                     35:  * 11-Oct-95   Dieter Siegmund (dieter) at NeXT
                     36:  *     Added performance hooks; changed transmit interrupt
                     37:  *     to only interrupt every N / 2 times, where N is the
                     38:  *     number of transmit descriptors.  This reduces the
                     39:  *      number of interrupts taken, and the amount of CPU
                     40:  *     used by the driver.
                     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:  *     Split out 21040 and 21041 connector auto-detect logic.
                     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: #import <machdep/ppc/proc_reg.h>
                     59: #import <mach/vm_param.h>                      // PAGE_SIZE
                     60: 
                     61: extern void                     *kernel_map;
                     62: extern kern_return_t            kmem_alloc_wired();
                     63: 
                     64: //#define DEBUG
                     65: 
                     66: #import "DECchip2104xInline.h"
                     67: 
                     68: #ifdef DEBUG
                     69: static void IOBreak()
                     70: {
                     71:     //IOBreakToDebugger();
                     72:     return;
                     73: }
                     74: 
                     75: static void printDesc(void *descriptorStruct)
                     76: {
                     77:     txDescriptorStruct *desc = (txDescriptorStruct *)descriptorStruct;
                     78:     
                     79:     IOLog("DESC: ");
                     80:     IOLog("%x (%x) ", (unsigned int)&desc->status.data, desc->status.data);
                     81:     IOLog("%x (%x: %x %x) ", (unsigned int)&desc->control.data, desc->control.data, desc->control.reg.byteCountBuffer1, desc->control.reg.byteCountBuffer2);
                     82:     IOLog("%x (%x) ", (unsigned int)&desc->bufferAddress1, desc->bufferAddress1);
                     83:     IOLog("%x (%x) ", (unsigned int)&desc->bufferAddress2, desc->bufferAddress2);
                     84:     IOLog("\n");
                     85:     
                     86: }
                     87: #endif DEBUG
                     88: 
                     89: /*
                     90:  * Breaks up an ethernet data buffer into two physical chunks. We know that
                     91:  * the buffer can't straddle more than two pages. If the content of paddr2 is
                     92:  * zero this means that all of the buffer lies in one physical page. Note
                     93:  * that we use the fact that tx and rx descriptors have the same size and
                     94:  * same layout of relevent fields (data address and count). 
                     95:  */
                     96: static BOOL 
                     97: IOUpdateDescriptorFromNetBuf(netbuf_t nb, void *desc, BOOL isReceive)
                     98: {
                     99:     IOReturn           result;
                    100:     vm_address_t       pageBreak;
                    101:     unsigned int       len;
                    102:     vm_address_t       vaddr;
                    103:     unsigned int       *paddr1, *paddr2;
                    104:     
                    105:     struct _descriptorStruct {
                    106:        unsigned int status;
                    107:        union   {
                    108:            struct {
                    109:                unsigned int
                    110:                    rsvd                :10,
                    111:                    byteCountBuffer2    :11,
                    112:                    byteCountBuffer1    :11;
                    113:            } reg;
                    114:            unsigned int data;
                    115:        } control;
                    116:        unsigned int bufferAddress1;
                    117:        unsigned int bufferAddress2;
                    118:     } *descriptorStruct;
                    119:     
                    120:     
                    121:     descriptorStruct = (struct _descriptorStruct *)desc;
                    122:     len = isReceive ? NETWORK_BUFSIZE : nb_size(nb);
                    123:     
                    124:     vaddr = (vm_address_t)nb_map(nb);
                    125:     paddr1 = &descriptorStruct->bufferAddress1;
                    126:     paddr2 = &descriptorStruct->bufferAddress2;
                    127:     
                    128:     /* Assume contiguity */
                    129:     *paddr2 = 0;
                    130:     descriptorStruct->control.reg.byteCountBuffer2 = 0;
                    131:     descriptorStruct->control.reg.byteCountBuffer1 = len;
                    132:     
                    133:     result = IOPhysicalFromVirtual(IOVmTaskSelf(), vaddr, paddr1);
                    134:     if (result != IO_R_SUCCESS) {
                    135:        return NO;
                    136:     }
                    137:     
                    138:     /*
                    139:      * Now check if this memory block crosses a page boundary. 
                    140:      */
                    141:     if (trunc_page(vaddr) == trunc_page(vaddr+len))    {
                    142:        return YES;
                    143:     }
                    144:     
                    145:     /* Nice try... */
                    146:     pageBreak = round_page(vaddr);
                    147:     descriptorStruct->control.reg.byteCountBuffer1 = pageBreak - vaddr;
                    148:     descriptorStruct->control.reg.byteCountBuffer2 = len - (pageBreak - vaddr);
                    149:     
                    150:     result = IOPhysicalFromVirtual(IOVmTaskSelf(), pageBreak, paddr2);
                    151:     if (result != IO_R_SUCCESS) {
                    152:        return NO;
                    153:     }
                    154:     
                    155:     return YES;
                    156: }
                    157: 
                    158: 
                    159: @implementation DECchip2104x (Private)
                    160: 
                    161: /*
                    162:  * Private functions
                    163:  */
                    164: - (BOOL)_allocateMemory
                    165: {
                    166:     int                        i;
                    167:     IOReturn           result;
                    168: 
                    169: //kprintf("[DECchip2104x _allocateMemory]\n");
                    170: 
                    171:     memorySize = sizeof(rxDescriptorStruct) * DEC_21X40_RX_RING_LENGTH
                    172:        + sizeof(txDescriptorStruct) * DEC_21X40_TX_RING_LENGTH
                    173:        + DEC_21X40_DESCRIPTOR_ALIGNMENT * 2
                    174:        + sizeof(setupBuffer_t) + DEC_21X40_DESCRIPTOR_ALIGNMENT;
                    175:     if (memorySize > PAGE_SIZE) {
                    176:        IOLog("%s: 1 page limit exceeded for descriptor memory\n",[self name]);
                    177:        return NO;
                    178:     }
                    179: 
                    180:     /*
                    181:      * We need one page of contiguous memory.
                    182:      */
                    183:     result = kmem_alloc_wired(kernel_map,(vm_offset_t *)&memoryPtr,memorySize);
                    184:     if (result != KERN_SUCCESS) {
                    185:         IOLog ("%s: can't allocate 0x%x bytes of memory\n",
                    186:               [self name], memorySize);
                    187:        return NO;
                    188:     }
                    189: 
                    190:     rxRing = (rxDescriptorStruct *)memoryPtr;
                    191:     if (!IOIsAligned(rxRing, DEC_21X40_DESCRIPTOR_ALIGNMENT))
                    192:        rxRing = IOAlign(rxDescriptorStruct *, rxRing, 
                    193:            DEC_21X40_DESCRIPTOR_ALIGNMENT);
                    194:     for (i = 0 ; i < DEC_21X40_RX_RING_LENGTH ; i++) {
                    195:        bzero((void *)&rxRing[i], sizeof(rxDescriptorStruct));
                    196:        rxNetbuf[i] = NULL;
                    197:     }
                    198:     
                    199:     txRing = (txDescriptorStruct *)(rxRing + DEC_21X40_RX_RING_LENGTH);
                    200:     if (!IOIsAligned(txRing, DEC_21X40_DESCRIPTOR_ALIGNMENT))
                    201:        txRing = IOAlign(txDescriptorStruct *, txRing, 
                    202:            DEC_21X40_DESCRIPTOR_ALIGNMENT);
                    203:     for (i = 0 ; i < DEC_21X40_TX_RING_LENGTH ; i++) {
                    204:        bzero((void *)&txRing[i], sizeof(txDescriptorStruct));
                    205:        txNetbuf[i] = NULL;
                    206:     }
                    207:     
                    208:     setupBuffer = (setupBuffer_t *)(txRing + DEC_21X40_TX_RING_LENGTH);
                    209:     if (!IOIsAligned(setupBuffer, DEC_21X40_DESCRIPTOR_ALIGNMENT))
                    210:        setupBuffer = IOAlign(setupBuffer_t *, 
                    211:                setupBuffer, DEC_21X40_DESCRIPTOR_ALIGNMENT);
                    212:     result = IOPhysicalFromVirtual(IOVmTaskSelf(),
                    213:        (vm_address_t)setupBuffer, (unsigned *)&setupBufferPhysical);
                    214:     if (result != IO_R_SUCCESS) {
                    215:         IOLog("%s: Invalid shared memory address\n", [self name]);
                    216:         return NO;
                    217:     }
                    218:     
                    219:     return YES;
                    220: }
                    221: 
                    222: #ifdef DEBUG
                    223: - (void)_dumpRegisters
                    224: {
                    225:     int i;
                    226:     
                    227:     return;
                    228:     IOLog("%s: Regs: ", [self name]);
                    229:     for (i = 0; i <= 15; i++) {
                    230:        IOLog("%02d: %x ", i, readCsr(ioBase, 8*i));
                    231:     }
                    232:     IOLog("\n");
                    233: }
                    234: #endif DEBUG
                    235: 
                    236: #ifdef DEBUG
                    237: - (void)_dumpDescriptor:(void *)ds
                    238: {
                    239:     txDescriptorStruct *desc = (txDescriptorStruct *)ds;
                    240:     
                    241:     IOLog("%s: Desc: ", [self name]);
                    242:     IOLog("%x  ", *(unsigned int *)&desc->status);
                    243:     IOLog("%x  ", *(unsigned int *)&desc->control);
                    244:     IOLog("%x  ", *(unsigned int *)&desc->bufferAddress1);
                    245:     IOLog("%x  ", *(unsigned int *)&desc->bufferAddress2);
                    246:     IOLog("\n");
                    247: }
                    248: #endif DEBUG
                    249: 
                    250: - (BOOL)_initTxRing
                    251: {
                    252:     unsigned int i;
                    253: 
                    254: //kprintf("[DECchip2104x _initTxRing]\n");
                    255:     
                    256:     for (i = 0; i < DEC_21X40_TX_RING_LENGTH; i++) {
                    257:        bzero((void *)&txRing[i], sizeof(txDescriptorStruct));
                    258:        txRing[i].status.reg.own = DEC_21X40_DESC_OWNED_BY_HOST;
                    259:        if (txNetbuf[i]) {
                    260:            nb_free(txNetbuf[i]);
                    261:            txNetbuf[i] = NULL;
                    262:        }
                    263:     }
                    264:     txRing[DEC_21X40_TX_RING_LENGTH-1].control.reg.ter = YES;
                    265:      
                    266:     txPutIndex = 0;
                    267:     txDoneIndex = 0;
                    268:     txNumFree = DEC_21X40_TX_RING_LENGTH;
                    269:     txIntCount = 0;
                    270: 
                    271:     /* Init the transmit queue. */
                    272:     if (transmitQueue) {
                    273:        [transmitQueue free];
                    274:     }
                    275:     transmitQueue = [[IONetbufQueue alloc] 
                    276:                        initWithMaxCount:TRANSMIT_QUEUE_SIZE];
                    277:     if (!transmitQueue)        {
                    278:         IOPanic("_initTxRing");
                    279:     }
                    280:     
                    281:     return YES;
                    282: }
                    283: 
                    284: - (BOOL)_initRxRing
                    285: {
                    286:     int        i;
                    287:     BOOL       status;
                    288: 
                    289: //kprintf("[DECchip2104x _initRxRing]\n");
                    290: 
                    291:     for (i = 0; i < DEC_21X40_RX_RING_LENGTH; i++) {
                    292:        bzero((void *)&rxRing[i], sizeof(rxDescriptorStruct));
                    293:        rxRing[i].status.reg.own = DEC_21X40_DESC_OWNED_BY_HOST;
                    294:        if (rxNetbuf[i] == NULL)        {
                    295:            rxNetbuf[i] = [self allocateNetbuf];
                    296:            if (rxNetbuf[i] == NULL)    {
                    297:                IOPanic("allocateNetbuf returned NULL in _initRxRing");
                    298:            }
                    299:        }
                    300:        status = IOUpdateDescriptorFromNetBuf(rxNetbuf[i], 
                    301:                        (void *)&rxRing[i], YES);
                    302:        if (status == NO)
                    303:            IOPanic("_initRxRing");
                    304:        rxRing[i].status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
                    305:     }
                    306:     
                    307:     rxRing[DEC_21X40_RX_RING_LENGTH-1].control.reg.rer = YES;
                    308: 
                    309:     rxDoneIndex = 0;
                    310:     
                    311:     return YES;
                    312: }
                    313: 
                    314: 
                    315: - (BOOL) _initChip
                    316: {
                    317: 
                    318: //kprintf("[DECchip2104x _initChip]\n");
                    319: 
                    320:     [self _initRegisters];
                    321:     [self _startTransmit];
                    322: 
                    323:     /*
                    324:      * Set up station, broadcast, and multicast addresses
                    325:      */
                    326:     if (![self _setAddressFiltering:YES])
                    327:        return NO;
                    328: 
                    329:     [self selectInterface];
                    330: 
                    331: #ifdef DEBUG
                    332:     [self _dumpRegisters];
                    333: #endif DEBUG
                    334:     
                    335:     return YES;
                    336: }
                    337: 
                    338: - (void)_resetChip
                    339: {
                    340:     csrRegUnion reg;
                    341: 
                    342: //kprintf("[DECchip2104x _resetChip]\n");
                    343:     
                    344:     reg.data = 0;
                    345:     reg.csr0.swr = 1;                  /* reset */
                    346:     writeCsr(ioBase, DEC_21X40_CSR0, reg.data);
                    347:     IODelay(100);
                    348:     reg.csr0.swr = 0;                  /* deassert */
                    349:     writeCsr(ioBase, DEC_21X40_CSR0, reg.data);
                    350:     
                    351:     IOSleep(1);                                /* >= 100 PCI bus cycles */
                    352: }
                    353: 
                    354: - (void)_startTransmit
                    355: {
                    356: 
                    357: //kprintf("[DECchip2104x _startTransmit]\n");
                    358: 
                    359:     operationMode.csr6.st = YES;
                    360:     writeCsr(ioBase, DEC_21X40_CSR6, operationMode.data);
                    361: }
                    362: 
                    363: - (void)_startReceive
                    364: {
                    365: 
                    366: //kprintf("[DECchip2104x _startReceive]\n");
                    367: 
                    368:     operationMode.csr6.sr = YES;
                    369:     writeCsr(ioBase, DEC_21X40_CSR6, operationMode.data);
                    370: }
                    371: 
                    372: - (void)_initRegisters
                    373: {
                    374:     IOReturn   result;
                    375:     csrRegUnion reg;
                    376:    
                    377:     unsigned int paddr;
                    378: 
                    379: //kprintf("[DECchip2104x _initRegisters]\n");
                    380:     
                    381:     [self _resetChip];
                    382:     
                    383:     reg.data = 0;
                    384:     reg.csr0.dbo = 1;           /* Big Endian Descriptors */
                    385: //    reg.csr0.ble = 1;           /* Big Endian Buffers */   
                    386:     reg.csr0.pbl = 16;         /* errata: don't set to 0 or 32 */
                    387:     reg.csr0.cal = 1;          /* depends upon NETWORK_BUFALIGNMENT */
                    388:     writeCsr(ioBase, DEC_21X40_CSR0, reg.data);                /* bus mode */
                    389:     
                    390:     result = IOPhysicalFromVirtual(IOVmTaskSelf(),
                    391:        (vm_address_t)rxRing, (unsigned int *)&paddr);
                    392:     if (result != IO_R_SUCCESS) {
                    393:         IOLog("%s: Invalid shared memory address\n", [self name]);
                    394:         return;
                    395:     }
                    396:     reg.data = 0;
                    397:     reg.csr3.rdlba = (unsigned int)paddr;
                    398:     writeCsr(ioBase, DEC_21X40_CSR3, reg.data);        /* receive list base */
                    399:     
                    400:     result = IOPhysicalFromVirtual(IOVmTaskSelf(),
                    401:        (vm_address_t)txRing, (unsigned int *)&paddr);
                    402:     if (result != IO_R_SUCCESS) {
                    403:         IOLog("%s: Invalid shared memory address\n", [self name]);
                    404:         return;
                    405:     }
                    406:     reg.data = 0;
                    407:     reg.csr4.tdlba = (unsigned int)paddr;
                    408:     writeCsr(ioBase, DEC_21X40_CSR4, reg.data);        /* transmit list base */
                    409: 
                    410:     reg.data = 0;      /* FIXME -- choose appropriate values */
                    411:     writeCsr(ioBase, DEC_21X40_CSR6, reg.data);        /* operations mode */
                    412:     operationMode.data = reg.data;
                    413:     
                    414:     reg.data = 0;
                    415:     reg.csr7.tim = reg.csr7.rim = reg.csr7.tjm = 1;
                    416:     reg.csr7.nim = 1;
                    417: #ifdef DEBUG    
                    418:     reg.csr7.tim = reg.csr7.tsm = reg.csr7.tum = reg.csr7.tjm = 1;
                    419:     reg.csr7.unm = reg.csr7.rim = reg.csr7.rum = 1;
                    420:     reg.csr7.atm = 1;
                    421:     reg.csr7.lfm = reg.csr7.sem = reg.csr7.aim = 1;
                    422: #endif DEBUG
                    423:     interruptMask.data = reg.data;
                    424:     
                    425:     writeCsr(ioBase, DEC_21X40_CSR11, 0);      /* no full duplex */
                    426: }
                    427: 
                    428: - (void)_transmitPacket:(netbuf_t)packet
                    429: {
                    430:     csrRegUnion                reg;
                    431:     txDescriptorStruct *desc;
                    432:     BOOL               status;
                    433: 
                    434: //kprintf("[DECchip2104x _transmitPacket]\n");
                    435:     
                    436:     [self performLoopback:packet];
                    437: 
                    438:     [self reserveDebuggerLock];
                    439: 
                    440:     if (txNumFree == 0) {
                    441:        [self releaseDebuggerLock];
                    442:        nb_free(packet);
                    443:        return;
                    444:     }
                    445:     
                    446:     desc = &txRing[txPutIndex];
                    447:     txNetbuf[txPutIndex] = packet;
                    448:     
                    449:     if (desc->control.reg.ter == 1) {
                    450:        desc->control.data = 0;
                    451:        desc->control.reg.ter = 1;
                    452:     } 
                    453:     else
                    454:        desc->control.data = 0;
                    455: 
                    456:     status = IOUpdateDescriptorFromNetBuf(packet, (void *)desc, NO);
                    457:     if (status == NO)  {
                    458:        [self releaseDebuggerLock];
                    459:        IOLog("%s: _transmitPacket: IOUpdateDescriptorFromNetBuf failed\n",
                    460:                [self name]);
                    461:        nb_free(packet);                /* this is the best we can do here */
                    462:        return;
                    463:     }
                    464:                
                    465:     desc->control.reg.fs = YES;
                    466:     desc->control.reg.ls = YES;
                    467:     if (++txIntCount == (DEC_21X40_TX_RING_LENGTH / 2)) {
                    468:        desc->control.reg.ic = YES;
                    469:        txIntCount = 0;
                    470:     }
                    471:     else
                    472:        desc->control.reg.ic = NO;
                    473: 
                    474:     desc->status.data = 0;
                    475:     desc->status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
                    476:     
                    477:     // txPutIndex = (txPutIndex + 1) % DEC_21X40_TX_RING_LENGTH;
                    478:     if (++txPutIndex == DEC_21X40_TX_RING_LENGTH)
                    479:        txPutIndex = 0;
                    480:     --txNumFree;
                    481: 
                    482:     /*  
                    483:      * Make the chip poll immediately.  
                    484:      */
                    485:     reg.data = 0;
                    486:     reg.csr1.tpd = YES;
                    487:     writeCsr(ioBase, DEC_21X40_CSR1, reg.data);
                    488: 
                    489:     [self releaseDebuggerLock];
                    490: 
                    491:     return;
                    492: }
                    493: 
                    494: /*
                    495:  * Method: receivePacket
                    496:  *
                    497:  * Purpose:
                    498:  *   Part of kerneldebugger protocol.
                    499:  */
                    500: - (void)receivePacket:(void *)pkt length:(unsigned int *)pkt_len
                    501:     timeout:(unsigned int)timeout
                    502: {
                    503:     *pkt_len = 0;
                    504:     timeout *= 1000;
                    505: 
                    506:     if (resetAndEnabled == NO)
                    507:        return;
                    508: 
                    509:     while (1) {
                    510:        if (rxRing[rxDoneIndex].status.reg.own  
                    511:            == DEC_21X40_DESC_OWNED_BY_HOST) {
                    512:            rxDescriptorStruct *        rds;
                    513: 
                    514:            rds = &rxRing[rxDoneIndex];
                    515:            if (rds->status.reg.es 
                    516:                || (!rds->status.reg.fs || !rds->status.reg.ls) 
                    517:                || (rds->status.reg.fl < ETHERMINPACKET)) {
                    518:                rxRing[rxDoneIndex].status.reg.own 
                    519:                    = DEC_21X40_DESC_OWNED_BY_CTRL;
                    520:                // rxDoneIndex = (rxDoneIndex + 1) % DEC_21X40_RX_RING_LENGTH;
                    521:                if (++rxDoneIndex == DEC_21X40_RX_RING_LENGTH)
                    522:                    rxDoneIndex = 0;
                    523:            }
                    524:            else
                    525:                break;
                    526:        }
                    527:        else {
                    528:            if ((int)timeout <= 0)
                    529:                return;
                    530:            IODelay(50);
                    531:            timeout -= 50;
                    532:        }
                    533:     }
                    534:     {
                    535:        rxDescriptorStruct *    rds;
                    536: 
                    537:        rds = &rxRing[rxDoneIndex];
                    538:        *pkt_len = rds->status.reg.fl - ETHERCRC;
                    539:        bcopy(nb_map(rxNetbuf[rxDoneIndex]), pkt, *pkt_len);
                    540: 
                    541:        rds->status.data = 0;
                    542:        rds->status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
                    543:        // rxDoneIndex = (rxDoneIndex + 1) % DEC_21X40_RX_RING_LENGTH;
                    544:        if (++rxDoneIndex == DEC_21X40_RX_RING_LENGTH)
                    545:            rxDoneIndex = 0;
                    546:     }
                    547:     return;
                    548: }
                    549: /*
                    550:  * Method: sendPacket
                    551:  *
                    552:  * Purpose:
                    553:  *   Part of kerneldebugger protocol.
                    554:  */
                    555: - (void)sendPacket:(void *)pkt length:(unsigned int)pkt_len
                    556: {
                    557:     int                                        size;
                    558:     volatile txDescriptorStruct        *       desc;
                    559:     csrRegUnion                                reg;
                    560:     BOOL                               status;
                    561: 
                    562:        if (resetAndEnabled == NO)
                    563:                return; /* can't transmit right now */
                    564:        
                    565:        [self _transmitInterruptOccurred];
                    566:        
                    567:     if (txNumFree == 0) {
                    568:                IOLog("%s: _sendPacket: No free tx descriptors\n", [self name]);
                    569:                return; /* can't transmit right now */
                    570:        }
                    571:        
                    572:     desc = &txRing[txPutIndex];
                    573:     txNetbuf[txPutIndex] = NULL;
                    574:     
                    575:     bcopy(pkt, nb_map(KDB_txBuf), pkt_len);
                    576:     size = nb_size(KDB_txBuf);
                    577:     nb_shrink_bot(KDB_txBuf, size - pkt_len);
                    578: 
                    579:     if (desc->control.reg.ter == 1) {
                    580:        desc->control.data = 0;
                    581:        desc->control.reg.ter = 1;
                    582:     } 
                    583:     else
                    584:        desc->control.data = 0;
                    585: 
                    586:     status = IOUpdateDescriptorFromNetBuf(KDB_txBuf, (void *)desc, NO);
                    587:     if (status == NO)  {
                    588:        IOLog("%s: _sendPacket: IOUpdateDescriptorFromNetBuf failed\n",
                    589:              [self name]);
                    590:        return;
                    591:     }
                    592:                
                    593:     desc->control.reg.fs = YES;
                    594:     desc->control.reg.ls = YES;
                    595:     desc->control.reg.ic = NO;
                    596:     desc->status.data = 0;
                    597:     desc->status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
                    598:     
                    599:     // txPutIndex = (txPutIndex + 1) % DEC_21X40_TX_RING_LENGTH;
                    600:     if (++txPutIndex == DEC_21X40_TX_RING_LENGTH)
                    601:        txPutIndex = 0;
                    602:     --txNumFree;
                    603: 
                    604:     /*  
                    605:      * Make the chip poll immediately.  
                    606:      */
                    607:     reg.data = 0;
                    608:     reg.csr1.tpd = YES;
                    609:     writeCsr(ioBase, DEC_21X40_CSR1, reg.data);
                    610:     
                    611:     { /* poll for completion */
                    612:        int i;
                    613:        for (i = 0; 
                    614:             i < 10000 && desc->status.reg.own == DEC_21X40_DESC_OWNED_BY_CTRL;
                    615:             i++) {
                    616:            IODelay(500);
                    617:        }
                    618:     }
                    619:     if (desc->status.reg.own == DEC_21X40_DESC_OWNED_BY_CTRL)
                    620:        IOLog("%s: _sendPacket: polling timed out\n", [self name]);
                    621: 
                    622:     /* restore the actual size of the buffer */
                    623:     nb_grow_bot(KDB_txBuf, size - pkt_len);
                    624: 
                    625:     return;
                    626: }
                    627: 
                    628: - (BOOL)_receiveInterruptOccurred
                    629: {
                    630:     netbuf_t                   packet;
                    631:     BOOL                       passPacketUp;
                    632:     rxDescriptorStruct *       rds;
                    633:     unsigned int               receivedFrameSize;
                    634:     BOOL                       status;
                    635: 
                    636: //kprintf("[DECchip2104x _receiveInterruptOccurred]\n");
                    637:     
                    638:     [self reserveDebuggerLock];
                    639:     
                    640:     while (rxRing[rxDoneIndex].status.reg.own
                    641:           == DEC_21X40_DESC_OWNED_BY_HOST) {
                    642:        passPacketUp = NO;
                    643:        rds = &rxRing[rxDoneIndex];
                    644:        receivedFrameSize = rds->status.reg.fl - ETHERCRC;
                    645:        
                    646:        /*
                    647:         * Bad packet. Just leave the netbuf in place.  
                    648:         */
                    649:        if (rds->status.reg.es
                    650:            || (!rds->status.reg.fs || !rds->status.reg.ls) 
                    651:            || (receivedFrameSize < (ETHERMINPACKET - ETHERCRC))) {
                    652:            [networkInterface incrementInputErrors];
                    653:            rxRing[rxDoneIndex].status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
                    654:            // rxDoneIndex = (rxDoneIndex + 1) % DEC_21X40_RX_RING_LENGTH;
                    655:            if (++rxDoneIndex == DEC_21X40_RX_RING_LENGTH)
                    656:                rxDoneIndex = 0;
                    657:            continue;
                    658:        }
                    659:        
                    660:        /*  Toss packets not in our multicast address-space.  */
                    661:        packet = rxNetbuf[rxDoneIndex];
                    662:        if (isPromiscuous 
                    663:            || rds->status.reg.mf == NO 
                    664:            || [super isUnwantedMulticastPacket:
                    665:                (ether_header_t *)nb_map(packet)] == NO) {
                    666:            netbuf_t newPacket;
                    667: 
                    668:            newPacket = [self allocateNetbuf];
                    669:            if (newPacket != NULL)      {
                    670:                rxNetbuf[rxDoneIndex] = newPacket;
                    671:                passPacketUp = YES;
                    672:                status = 
                    673:                    IOUpdateDescriptorFromNetBuf(rxNetbuf[rxDoneIndex], 
                    674:                                                 (void *)&rxRing[rxDoneIndex], 
                    675:                                                 YES);
                    676:                if (status == NO) {
                    677:                    IOPanic("DECchip21040: IOUpdateDescriptorFromNetBuf\n"); 
                    678:                }
                    679:                /*  Adjust to size received */
                    680:                nb_shrink_bot(packet, nb_size(packet) - receivedFrameSize);
                    681:            } 
                    682:        }
                    683:        rds->status.data = 0;
                    684:        rds->status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
                    685:        
                    686:        // rxDoneIndex = (rxDoneIndex + 1) % DEC_21X40_RX_RING_LENGTH;
                    687:        if (++rxDoneIndex == DEC_21X40_RX_RING_LENGTH)
                    688:            rxDoneIndex = 0;
                    689:        if (passPacketUp) {
                    690:            passPacketUp = NO;
                    691:            [self releaseDebuggerLock];
                    692:            [networkInterface handleInputPacket:packet extra:0];
                    693:            [self reserveDebuggerLock];
                    694:        }
                    695:     }
                    696: 
                    697:     [self releaseDebuggerLock];
                    698:     
                    699:     return YES;
                    700: }
                    701: 
                    702: - (BOOL)_transmitInterruptOccurred
                    703: {
                    704:     txDescriptorStruct         *tds;
                    705: 
                    706: //kprintf("[DECchip2104x _transmitInterruptOccurred]\n");
                    707:     
                    708:     while (txNumFree < DEC_21X40_TX_RING_LENGTH) { 
                    709:        tds = &txRing[txDoneIndex];
                    710:        if (tds->status.reg.own == DEC_21X40_DESC_OWNED_BY_CTRL)
                    711:            break;
                    712:        
                    713:        if (tds->control.reg.set == 1)  {
                    714:            //IOLog("TX interrupt: Ignoring set up packet\n");
                    715:            // txDoneIndex = (txDoneIndex + 1) % DEC_21X40_TX_RING_LENGTH;
                    716:            if (++txDoneIndex == DEC_21X40_TX_RING_LENGTH)
                    717:                txDoneIndex = 0;
                    718:            ++txNumFree;
                    719:            continue;
                    720:        }
                    721: 
                    722:        if (tds->status.reg.uf || tds->status.reg.ec
                    723:                || tds->status.reg.lc || tds->status.reg.nc 
                    724:                || tds->status.reg.to)
                    725:            [networkInterface incrementOutputErrors];
                    726:        else
                    727:            [networkInterface incrementOutputPackets];
                    728:        
                    729:        if (tds->status.reg.ec)
                    730:            [networkInterface incrementCollisionsBy:16];
                    731:        else if (tds->status.reg.cc)
                    732:            [networkInterface incrementCollisionsBy:tds->status.reg.cc];
                    733:        if (tds->status.reg.lc && !tds->status.reg.uf)
                    734:            [networkInterface incrementCollisions];
                    735:            
                    736:         if (txNetbuf[txDoneIndex] != NULL) {
                    737:            nb_free(txNetbuf[txDoneIndex]);
                    738:            txNetbuf[txDoneIndex] = NULL;
                    739:        }
                    740:        // txDoneIndex = (txDoneIndex + 1) % DEC_21X40_TX_RING_LENGTH;
                    741:        if (++txDoneIndex == DEC_21X40_TX_RING_LENGTH)
                    742:            txDoneIndex = 0;
                    743:        ++txNumFree;
                    744:     }
                    745:     
                    746:     return YES;
                    747: }
                    748: 
                    749: #define DEC_21X40_SETUP_TIMEOUT        10000
                    750: 
                    751: - (BOOL)_loadSetupFilter:(BOOL)pollingMode
                    752: {
                    753:     txDescriptorStruct         *setupDescriptor;
                    754:     unsigned int       time = DEC_21X40_SETUP_TIMEOUT;
                    755:     csrRegUnion                reg;
                    756: 
                    757: //kprintf("[DECchip2104x _loadSetupFilter]\n");
                    758:     
                    759:     /*
                    760:      * Make sure that we have a descriptor for setup frame
                    761:      */
                    762:     if (txNumFree == 0)
                    763:        return NO;
                    764: 
                    765:     setupDescriptor = &txRing[txPutIndex];
                    766:     // txPutIndex = (txPutIndex + 1) % DEC_21X40_TX_RING_LENGTH;
                    767:     if (++txPutIndex == DEC_21X40_TX_RING_LENGTH)
                    768:        txPutIndex = 0;
                    769:     --txNumFree;
                    770: 
                    771:     /*
                    772:      * Initialize the Setup descriptor
                    773:      */
                    774:     if (setupDescriptor->control.reg.ter == YES)       {
                    775:        setupDescriptor->control.data = 0;
                    776:        setupDescriptor->control.reg.ter = YES;
                    777:     } else {
                    778:        setupDescriptor->control.data = 0;
                    779:     }
                    780:     
                    781:     setupDescriptor->control.reg.set = YES;
                    782:     setupDescriptor->control.reg.ic = YES;
                    783:     setupDescriptor->control.reg.byteCountBuffer1 = 
                    784:                sizeof(setupBuffer_t);
                    785:     setupDescriptor->control.reg.byteCountBuffer2 = 0;
                    786: 
                    787:     setupDescriptor->bufferAddress1 = setupBufferPhysical;
                    788:     setupDescriptor->bufferAddress2 = 0;
                    789: 
                    790:     setupDescriptor->status.data = 0;
                    791:     setupDescriptor->status.reg.own = DEC_21X40_DESC_OWNED_BY_CTRL;
                    792: 
                    793:     /* tell the chip about this setup command */
                    794:     reg.data = 0;
                    795:     reg.csr1.tpd = YES;
                    796:     writeCsr(ioBase, DEC_21X40_CSR1, reg.data);
                    797:     
                    798:     if (pollingMode) {
                    799:        while (time--) {
                    800:            IODelay(5);
                    801:            reg.data = readCsr(ioBase, DEC_21X40_CSR5);
                    802:            if (reg.csr5.tu) {
                    803:                writeCsr(ioBase, DEC_21X40_CSR5, reg.data);
                    804:                break;
                    805:            }
                    806:        }
                    807: 
                    808:        // txDoneIndex = (txDoneIndex + 1) % DEC_21X40_TX_RING_LENGTH;
                    809:        if (++txDoneIndex == DEC_21X40_TX_RING_LENGTH)
                    810:            txDoneIndex = 0;
                    811:        ++txNumFree;
                    812:     }
                    813:     
                    814:     return YES;
                    815: }
                    816: 
                    817: - (BOOL)_setAddressFiltering:(BOOL)pollingMode 
                    818: {
                    819:     int                        i;
                    820:     BOOL               status = YES;                           
                    821:     unsigned           q_count;        
                    822:     unsigned short     *address;
                    823: 
                    824: //kprintf("[DECchip2104x _setAddressFiltering]\n");
                    825: 
                    826:     /*
                    827:      * Copy station address into the first entry.  Note that the
                    828:      * upper 2 bytes of all longwords in the setup frame are don't
                    829:      * cares for perfect filtering.
                    830:      */
                    831:     address = (unsigned short *)&myAddress;
                    832:     for (i = 0 ; i < 3; i++) {
                    833:       unsigned short addr = (unsigned short)*address++;
                    834:       setupBuffer->physicalAddress[0][i] = (addr << 16);
                    835:     }
                    836: 
                    837:     /*
                    838:      * Load the broadcast address in the second entry
                    839:      */
                    840:     for (i = 0 ; i < 3; i++) {
                    841:          setupBuffer->physicalAddress[1][i] = 0xffffffff;
                    842:     }
                    843: 
                    844:     /*
                    845:      * Skip over the first 2 entries
                    846:      */
                    847:     q_count = 2;
                    848:         
                    849:     if (multicastEnabled) {
                    850:         enetMulti_t             *multiAddr;
                    851:         queue_head_t            *multiQueue = [super multicastQueue];
                    852: 
                    853:         if (!queue_empty(multiQueue)) {
                    854:             /*
                    855:              * Fill in the addresses
                    856:              */
                    857:             queue_iterate(multiQueue, multiAddr, enetMulti_t *, link) {
                    858:                union {
                    859:                      unsigned char     bytes[4];
                    860:                      unsigned long     word;
                    861:                } typeConvert; 
                    862: 
                    863:                typeConvert.word = 0;
                    864: 
                    865:                for (i = 0; i < 3; i++) {
                    866:                    typeConvert.bytes[0] = multiAddr->address.ea_byte[i*2];
                    867:                    typeConvert.bytes[1] = multiAddr->address.ea_byte[i*2+1];
                    868:                    setupBuffer->physicalAddress[q_count][i] = 
                    869:                        typeConvert.word;
                    870:                }
                    871:                if (++q_count >= DEC_21X40_SETUP_PERFECT_ENTRIES) {
                    872:                    IOLog("%s: %d multicast address limit exceeded\n",
                    873:                        [self name], DEC_21X40_SETUP_PERFECT_MCAST_ENTRIES);
                    874:                    break;
                    875:                }
                    876:            }
                    877:        }
                    878:     }
                    879:     
                    880:     /* 
                    881:      * Duplicate station address for remaining entries
                    882:      */
                    883:     for (; q_count < DEC_21X40_SETUP_PERFECT_ENTRIES; ++q_count) {
                    884:        bcopy(setupBuffer->physicalAddress[0], 
                    885:            setupBuffer->physicalAddress[q_count], 
                    886:            3 * sizeof (long));
                    887:     }
                    888: 
                    889:     if (![self _loadSetupFilter:pollingMode])
                    890:        status = NO;
                    891: 
                    892:     return status;
                    893: }
                    894: 
                    895: 
                    896: @end
                    897: 

unix.superglobalmegacorp.com

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