Annotation of XNU/osfmk/kdp/pe/POWERMAC/kdp_mace.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) 1997 Apple Computer, Inc.
                     24:  *
                     25:  * ethernet driver for mace on-board ethernet
                     26:  *
                     27:  * HISTORY
                     28:  *
                     29:  * Dieter Siegmund ([email protected]) Thu Feb 27 18:25:33 PST 1997
                     30:  * - ripped off code from MK/LINUX, turned it into a polled-mode
                     31:  *   driver for the PCI (8500) class machines
                     32:  *
                     33:  * Dieter Siegmund ([email protected]) Fri Mar 21 12:41:29 PST 1997
                     34:  * - reworked to support a BSD-style interface, and to support kdb polled
                     35:  *   interface and interrupt-driven interface concurrently
                     36:  *
                     37:  * Justin Walker ([email protected]) Tue May 20 10:29:29 PDT 1997
                     38:  * - Added multicast support
                     39:  *
                     40:  * Dieter Siegmund ([email protected]) Thu May 29 15:02:29 PDT 1997
                     41:  * - fixed problem with sending arp packets for ip address 0.0.0.0
                     42:  * - use kdp_register_send_receive() instead of defining 
                     43:  *   en_send_pkt/en_recv_pkt routines to avoid name space 
                     44:  *   collisions with IOEthernetDebugger and allow these routines to be
                     45:  *   overridden by a driverkit-style driver
                     46:  *
                     47:  * Dieter Siegmund ([email protected]) Tue Jun 24 18:29:15 PDT 1997
                     48:  * - don't let the adapter auto-strip 802.3 receive frames, it messes
                     49:  *   up the frame size logic
                     50:  *
                     51:  * Dieter Siegmund ([email protected]) Tue Aug  5 16:24:52 PDT 1997
                     52:  * - handle multicast address deletion correctly
                     53:  */
                     54: #ifdef MACE_DEBUG
                     55: /*
                     56:  * Caveat: MACE_DEBUG delimits some code that is getting kind of
                     57:  *         stale. Before blindly turning on MACE_DEBUG for your
                     58:  *         testing, take a look at the code enabled by it to check
                     59:  *         that it is reasonably sane.
                     60:  */
                     61: #endif
                     62: 
                     63: #include <mach/boolean.h>
                     64: #include <mach/exception_types.h>
                     65: #include <mach/mach_types.h>
                     66: 
                     67: #include <ppc/proc_reg.h>
                     68: #include <ppc/pmap.h>
                     69: #include <pexpert/ppc/powermac.h>
                     70: #include <pexpert/ppc/dbdma.h>
                     71: #include <kdp/kdp_en_debugger.h>
                     72: #include <kdp/kdp_udp.h>
                     73: 
                     74: #include "kdp_mace.h"
                     75: 
                     76: struct kdp_mace_copy_desc {
                     77:     int *       len;
                     78:     char *      data;
                     79: };
                     80: static mace_t  mace;
                     81:  
                     82: #define MACE_DMA_AREA_SIZE \
                     83:                 (ETHER_RX_NUM_DBDMA_BUFS * ETHERNET_BUF_SIZE + PG_SIZE)
                     84: static unsigned long 
                     85:        mace_rx_dma_area[(MACE_DMA_AREA_SIZE + 
                     86:                                sizeof(long))/sizeof(long)];                
                     87: static unsigned long 
                     88:        mace_tx_dma_area[(ETHERNET_BUF_SIZE + PG_SIZE + 
                     89:                                sizeof(long))/sizeof(long)];
                     90:  
                     91: #ifdef MACE_DEBUG
                     92: static unsigned char testBuffer[PG_SIZE * 4];
                     93: static unsigned char testMsg[] = "mace ethernet interface test";
                     94: #endif
                     95: 
                     96: static void polled_send_pkt(char * data, int len);
                     97: static void polled_receive_pkt(char *data, int *len, int timeout_ms);
                     98: 
                     99: void kdp_mace_reset(mace_t *);
                    100: void kdp_mace_geteh(unsigned char *);
                    101: void kdp_mace_setup_dbdma(void);
                    102: boolean_t kdp_mace_init(void * baseAddresses[3], unsigned char * netAddr);
                    103: #ifdef MACE_DEBUG
                    104: static void printContiguousEtherPacket(u_char *, int);
                    105: static void send_test_packet(void);
                    106: #endif
                    107: 
                    108: typedef int (*funcptr)(char *, int, void *);
                    109: int kdp_mace_recv_pkt(funcptr , void *);
                    110: 
                    111: #ifdef MACE_DEBUG
                    112: static int
                    113: macAddrsEqual(unsigned char * one, unsigned char * two)
                    114: {
                    115:     int i;
                    116: 
                    117:     for (i = 0; i < NUM_EN_ADDR_BYTES; i++)
                    118:        if (*one++ != *two++)
                    119:            return 0;
                    120:     return 1;
                    121: }
                    122: 
                    123: static __inline__ int
                    124: isprint(unsigned char c)
                    125: {
                    126:     return (c >= 0x20 && c <= 0x7e);
                    127: }
                    128: 
                    129: static void
                    130: printEtherHeader(enet_addr_t * dh, enet_addr_t * sh, u_short etype)
                    131: {
                    132:     u_char * dhost = dh->ether_addr_octet; 
                    133:     u_char * shost = sh->ether_addr_octet;
                    134: 
                    135:     printf("Dst: %x:%x:%x:%x:%x:%x Src: %x:%x:%x:%x:%x:%x Type: 0x%x\n", 
                    136:            dhost[0], dhost[1], dhost[2], dhost[3], dhost[4], dhost[5],
                    137:            shost[0], shost[1], shost[2], shost[3], shost[4], shost[5],
                    138:            etype);
                    139: }
                    140: 
                    141: static void
                    142: printData(u_char * data_p, int n_bytes)
                    143: {
                    144: #define CHARS_PER_LINE         16
                    145:     char               line_buf[CHARS_PER_LINE + 1];
                    146:     int                        line_pos;
                    147:     int                        offset;
                    148: 
                    149:     for (line_pos = 0, offset = 0; offset < n_bytes; offset++, data_p++) {
                    150:        if (line_pos == 0) {
                    151:            printf("%04d ", offset);
                    152:        }
                    153: 
                    154:        line_buf[line_pos] = isprint(*data_p) ? *data_p : '.';
                    155:        printf(" %02x", *data_p);
                    156:        line_pos++;
                    157:        if (line_pos == CHARS_PER_LINE) {
                    158:            line_buf[CHARS_PER_LINE] = '\0';
                    159:            printf("  %s\n", line_buf);
                    160:            line_pos = 0;
                    161:        }
                    162:     }
                    163:     if (line_pos) { /* need to finish up the line */
                    164:        for (; line_pos < CHARS_PER_LINE; line_pos++) {
                    165:            printf("   ");
                    166:            line_buf[line_pos] = ' ';
                    167:        }
                    168:        line_buf[CHARS_PER_LINE] = '\0';
                    169:        printf("  %s\n", line_buf);
                    170:     }
                    171: }
                    172: 
                    173: static void
                    174: printEtherPacket(enet_addr_t * dhost, enet_addr_t * shost, u_short type, 
                    175:                 u_char * data_p, int n_bytes)
                    176: {
                    177:     printEtherHeader(dhost, shost, type);
                    178:     printData(data_p, n_bytes);
                    179: }
                    180: 
                    181: static void
                    182: printContiguousEtherPacket(u_char * data_p, int n_bytes)
                    183: {
                    184:     printEtherPacket((enet_addr_t *)data_p, 
                    185:                     (enet_addr_t *)(data_p + NUM_EN_ADDR_BYTES), 
                    186:                     *((u_short *)(data_p + (NUM_EN_ADDR_BYTES * 2))),
                    187:                     data_p, n_bytes);
                    188: }
                    189: #endif
                    190: 
                    191: 
                    192: /*
                    193:  * kdp_mace_reset
                    194:  *
                    195:  * Reset the board..
                    196:  */
                    197: void
                    198: kdp_mace_reset(mace_t * m)
                    199: {
                    200:     dbdma_reset(m->rv_dbdma);
                    201:     dbdma_reset(m->tx_dbdma);
                    202: }
                    203: 
                    204: 
                    205: /*
                    206:  * kdp_mace_geteh:
                    207:  *
                    208:  *     This function gets the ethernet address (array of 6 unsigned
                    209:  *     bytes) from the MACE board registers.
                    210:  *
                    211:  */
                    212: void
                    213: kdp_mace_geteh(unsigned char *ep)
                    214: {
                    215:     int        i;
                    216:     unsigned char ep_temp;
                    217: 
                    218:     mace.ereg->iac = IAC_PHYADDR; eieio();
                    219:        
                    220:     for (i = 0; i < ETHER_ADD_SIZE; i++) {
                    221:        ep_temp = mace.ereg->padr; eieio();
                    222:        *ep++ = ep_temp;
                    223:     }
                    224: }
                    225: 
                    226: /*
                    227:  * mace_seteh:
                    228:  *
                    229:  *     This function sets the ethernet address (array of 6 unsigned
                    230:  *     bytes) on the MACE board. 
                    231:  */
                    232: static void
                    233: mace_seteh(unsigned char *ep)
                    234: {
                    235:     int        i;
                    236:     unsigned char      status;
                    237: 
                    238:     if (mace.chip_id != MACE_REVISION_A2) {
                    239:        mace.ereg->iac = IAC_ADDRCHG|IAC_PHYADDR; eieio();
                    240: 
                    241:        while ((status = mace.ereg->iac)) {
                    242:            if ((status & IAC_ADDRCHG) == 0) {
                    243:                eieio();
                    244:                break;
                    245:            }
                    246:            eieio();
                    247:        }
                    248:     }
                    249:     else {
                    250:        /* start to load the address.. */
                    251:        mace.ereg->iac = IAC_PHYADDR; eieio();
                    252:     }
                    253: 
                    254:     for (i = 0; i < NUM_EN_ADDR_BYTES; i++) {
                    255:        mace.ereg->padr = *(ep+i); eieio();
                    256:     }
                    257:     return;
                    258: }
                    259: 
                    260: /*
                    261:  * kdp_mace_setup_dbdma
                    262:  *
                    263:  * Setup various dbdma pointers.
                    264:  */
                    265: void
                    266: kdp_mace_setup_dbdma()
                    267: {
                    268:     mace_t *           m = &mace;
                    269:     int                        i;
                    270:     dbdma_command_t *  d;
                    271:     vm_offset_t                address;
                    272:     dbdma_regmap_t *   regmap;
                    273: 
                    274: #define ALIGN_MASK     0xfffffffcUL
                    275:     if (m->rv_dma_area == 0) {
                    276:        m->rv_dma_area = (unsigned char *)
                    277:            ((((unsigned long)mace_rx_dma_area) + 3) & ALIGN_MASK);
                    278:        m->rv_dma = dbdma_alloc(ETHER_RX_NUM_DBDMA_BUFS + 2);
                    279:        m->tx_dma = dbdma_alloc(TX_NUM_DBDMA);
                    280:        m->tx_dma_area = (unsigned char *)
                    281:            ((((unsigned long)mace_tx_dma_area) + 3) & ALIGN_MASK);
                    282:     }
                    283: 
                    284:     /* set up a ring of buffers */
                    285:     d = m->rv_dma;
                    286:     for (i = 0; i < ETHER_RX_NUM_DBDMA_BUFS; i++, d++) {
                    287:        address = (vm_offset_t) kvtophys((vm_offset_t)&m->rv_dma_area[i*ETHERNET_BUF_SIZE]);
                    288:        DBDMA_BUILD(d, DBDMA_CMD_IN_LAST, 0, ETHERNET_BUF_SIZE,
                    289:                    address, DBDMA_INT_ALWAYS,
                    290:                    DBDMA_WAIT_NEVER, 
                    291:                    DBDMA_BRANCH_NEVER);
                    292:     }
                    293: 
                    294:     /* stop when we hit the end of the list */
                    295:     DBDMA_BUILD(d, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_ALWAYS,
                    296:                DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
                    297:     d++;
                    298: 
                    299:     /* branch to command at "address" ie. element 0 of the "array" */
                    300:     DBDMA_BUILD(d, DBDMA_CMD_NOP, 0, 0, 0, DBDMA_INT_NEVER,
                    301:                DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS);
                    302:     address = (vm_offset_t) kvtophys((vm_offset_t)m->rv_dma);
                    303:     dbdma_st4_endian(&d->d_cmddep, address);
                    304: 
                    305:     m->rv_head = 0;
                    306:     m->rv_tail = ETHER_RX_NUM_DBDMA_BUFS; /* always contains DBDMA_CMD_STOP */
                    307:     regmap = m->rv_dbdma;
                    308: 
                    309:     /* stop/init/restart dma channel */
                    310:     dbdma_reset(regmap);
                    311:     dbdma_reset(m->tx_dbdma);
                    312: 
                    313:     /* Set the wait value.. */
                    314:     dbdma_st4_endian(&regmap->d_wait, DBDMA_SET_CNTRL(0x00));
                    315: 
                    316:     /* Set the tx wait value */
                    317:     regmap = m->tx_dbdma;
                    318:     dbdma_st4_endian(&regmap->d_wait, DBDMA_SET_CNTRL(0x20));
                    319: 
                    320:     flush_dcache((vm_offset_t)m->rv_dma, 
                    321:                  sizeof(dbdma_command_t) * (ETHER_RX_NUM_DBDMA_BUFS + 2),
                    322:                        FALSE);
                    323:     /* start receiving */
                    324:     dbdma_start(m->rv_dbdma, m->rv_dma);
                    325: }
                    326: 
                    327: #ifdef MACE_DEBUG
                    328: static void
                    329: send_test_packet()
                    330: {
                    331:     unsigned char * tp;
                    332: 
                    333:     bzero((char *)testBuffer, sizeof(testBuffer));
                    334: 
                    335:     tp = testBuffer;
                    336: 
                    337:     /* send self-addressed packet */
                    338:     bcopy((char *)&mace.macaddr[0], (char *)tp, NUM_EN_ADDR_BYTES);
                    339:     tp += NUM_EN_ADDR_BYTES;
                    340:     bcopy((char *)&mace.macaddr[0], (char *)tp, NUM_EN_ADDR_BYTES);
                    341:     tp += NUM_EN_ADDR_BYTES;
                    342:     *tp++ = 0;
                    343:     *tp++ = 0;
                    344:     bcopy((char *)testMsg, (char *)tp, sizeof(testMsg));
                    345:     polled_send_pkt((char *)testBuffer, 80);
                    346:     return;
                    347: }
                    348: #endif
                    349: 
                    350: /*
                    351:  * Function: kdp_mace_init
                    352:  *
                    353:  * Purpose:
                    354:  *   Called early on, initializes the adapter and readies it for
                    355:  *   kdb kernel debugging. 
                    356:  */
                    357: boolean_t
                    358: kdp_mace_init(void * baseAddresses[3], unsigned char * netAddr)
                    359: {
                    360:     unsigned char      status;
                    361:     mace_t *           m = &mace;
                    362:     struct mace_board * ereg;
                    363:     int                mpc = 0;
                    364:     int                        i;
                    365: 
                    366:     bzero((char *)&mace, sizeof(mace));
                    367: 
                    368:     /* get the ethernet registers' mapped address */
                    369:     ereg = m->ereg 
                    370:        = (struct mace_board *) baseAddresses[0];
                    371:     m->tx_dbdma = (dbdma_regmap_t *) baseAddresses[1];
                    372:     m->rv_dbdma = (dbdma_regmap_t *) baseAddresses[2];
                    373: 
                    374:     for (i = 0; i < NUM_EN_ADDR_BYTES; i++)
                    375:         m->macaddr[i] = netAddr[i];
                    376: 
                    377:     /* Reset the board & AMIC.. */
                    378:     kdp_mace_reset(m);
                    379: 
                    380:     /* grab the MACE chip rev  */
                    381:     m->chip_id = (ereg->chipid2 << 8 | ereg->chipid1);
                    382: 
                    383:     /* don't auto-strip for 802.3 */
                    384:     m->ereg->rcvfc &= ~(RCVFC_ASTRPRCV);
                    385: 
                    386:     /* set the ethernet address */
                    387:     mace_seteh(mace.macaddr);
                    388:     {
                    389:        unsigned char macaddr[NUM_EN_ADDR_BYTES];
                    390:        kdp_mace_geteh(macaddr);
                    391:        printf("mace ethernet [%02x:%02x:%02x:%02x:%02x:%02x]\n",
                    392:                macaddr[0], macaddr[1], macaddr[2], 
                    393:                macaddr[3], macaddr[4], macaddr[5]);
                    394:     }
                    395: 
                    396:     /* Now clear the Multicast filter */
                    397:     if (m->chip_id != MACE_REVISION_A2) {
                    398:        ereg->iac = IAC_ADDRCHG|IAC_LOGADDR; eieio();
                    399: 
                    400:        while ((status = ereg->iac)) {
                    401:            if ((status & IAC_ADDRCHG) == 0)
                    402:                break;
                    403:            eieio();
                    404:        }
                    405:        eieio();
                    406:     }
                    407:     else {
                    408:        ereg->iac = IAC_LOGADDR; eieio();
                    409:     }
                    410:     {
                    411:        int i;
                    412: 
                    413:        for (i=0; i < 8; i++) 
                    414:        {    ereg->ladrf = 0;
                    415:             eieio();
                    416:         }
                    417:     }
                    418: 
                    419:     /* register interrupt routines */
                    420:     kdp_mace_setup_dbdma();
                    421: 
                    422:     /* Start the chip... */
                    423:     m->ereg->maccc = MACCC_ENXMT|MACCC_ENRCV; eieio();
                    424:     {
                    425:        volatile char ch =  mace.ereg->ir; eieio();
                    426:     }
                    427: 
                    428:     delay(500); /* paranoia */
                    429:     mace.ereg->imr = 0xfe; eieio();
                    430: 
                    431:     /* register our debugger routines */
                    432:     kdp_register_send_receive((kdp_send_t)polled_send_pkt, 
                    433:                              (kdp_receive_t)polled_receive_pkt);
                    434: 
                    435: #ifdef MACE_DEBUG
                    436:     printf("Testing 1 2 3\n");
                    437:     send_test_packet();
                    438:     printf("Testing 1 2 3\n");
                    439:     send_test_packet();
                    440:     printf("Testing 1 2 3\n");
                    441:     send_test_packet();
                    442:     do {
                    443:        static unsigned char buf[ETHERNET_BUF_SIZE];
                    444:        int len;
                    445:        int nmpc = mace.ereg->mpc; eieio();
                    446: 
                    447:        if (nmpc > mpc) {
                    448:            mpc = nmpc;
                    449:            printf("mpc %d\n", mpc);
                    450:        }
                    451:        polled_receive_pkt((char *)buf, &len, 100);
                    452:        if (len > 0) {
                    453:            printf("rx %d\n", len);
                    454:            printContiguousEtherPacket(buf, len);
                    455:        }
                    456:     } while(1);
                    457: #endif
                    458: 
                    459:     return TRUE;
                    460: }
                    461: 
                    462: #ifdef MACE_DEBUG
                    463: static void
                    464: kdp_mace_txstatus(char * msg)
                    465: {
                    466:     dbdma_regmap_t *           dmap = mace.tx_dbdma;
                    467:     volatile unsigned long     status;
                    468:     volatile unsigned long     intr;
                    469:     volatile unsigned long     branch;
                    470:     volatile unsigned long     wait;
                    471: 
                    472:     status = dbdma_ld4_endian(&dmap->d_status); eieio();
                    473:     intr = dbdma_ld4_endian(&dmap->d_intselect); eieio();
                    474:     branch = dbdma_ld4_endian(&dmap->d_branch); eieio();
                    475:     wait = dbdma_ld4_endian(&dmap->d_wait); eieio();
                    476:     printf("(%s s=0x%x i=0x%x b=0x%x w=0x%x)", msg, status, intr, branch,
                    477:           wait);
                    478:     return;
                    479: }
                    480: #endif
                    481: 
                    482: static void
                    483: kdp_mace_tx_dbdma(char * data, int len)
                    484: {
                    485:     unsigned long      count;
                    486:     dbdma_command_t *  d;
                    487:     unsigned long      page;
                    488: 
                    489:     d = mace.tx_dma;
                    490:     page = ((unsigned long) data) & PG_MASK;
                    491:     if ((page + len) <= PG_SIZE) { /* one piece dma */
                    492:        DBDMA_BUILD(d, DBDMA_CMD_OUT_LAST, DBDMA_KEY_STREAM0,
                    493:                    len,
                    494:                    (vm_offset_t) kvtophys((vm_offset_t) data),
                    495:                    DBDMA_INT_NEVER, 
                    496:                    DBDMA_WAIT_IF_FALSE, DBDMA_BRANCH_NEVER);
                    497:     }
                    498:     else { /* two piece dma */
                    499:        count = PG_SIZE - page;
                    500:        DBDMA_BUILD(d, DBDMA_CMD_OUT_MORE, DBDMA_KEY_STREAM0,
                    501:                    count,
                    502:                    (vm_offset_t)kvtophys((vm_offset_t) data),
                    503:                    DBDMA_INT_NEVER, 
                    504:                    DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
                    505:        d++;
                    506:        DBDMA_BUILD(d, DBDMA_CMD_OUT_LAST, DBDMA_KEY_STREAM0, 
                    507:                    len - count, (vm_offset_t)
                    508:                    kvtophys((vm_offset_t)((unsigned char *)data + count)),
                    509:                    DBDMA_INT_NEVER, 
                    510:                    DBDMA_WAIT_IF_FALSE, DBDMA_BRANCH_NEVER);
                    511:     }
                    512:     d++;
                    513:     DBDMA_BUILD(d, DBDMA_CMD_LOAD_QUAD, DBDMA_KEY_SYSTEM,
                    514:                1, kvtophys((vm_offset_t) &mace.ereg->xmtfs),DBDMA_INT_NEVER, 
                    515: //             1, &mace.ereg->xmtfs,DBDMA_INT_NEVER, 
                    516:                DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
                    517:     d++;
                    518:     DBDMA_BUILD(d, DBDMA_CMD_LOAD_QUAD, DBDMA_KEY_SYSTEM,
                    519:                1, kvtophys((vm_offset_t) &mace.ereg->ir), DBDMA_INT_ALWAYS,
                    520: //             1, &mace.ereg->ir, DBDMA_INT_ALWAYS,
                    521:                DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
                    522:     d++;
                    523:     DBDMA_BUILD(d, DBDMA_CMD_STOP, 0, 0, 0, 0, 0, 0);
                    524: 
                    525:     flush_dcache((vm_offset_t)mace.tx_dma, 
                    526:                sizeof(dbdma_command_t) * TX_NUM_DBDMA,
                    527:                FALSE);
                    528:     dbdma_start(mace.tx_dbdma, mace.tx_dma);
                    529:     return;
                    530: 
                    531: }
                    532: 
                    533: static void
                    534: waitForDBDMADone(char * msg)
                    535: {
                    536:     {
                    537:        /* wait for tx dma completion */
                    538:        dbdma_regmap_t *        dmap = mace.tx_dbdma;
                    539:        int                     i;
                    540:        volatile unsigned long  val;
                    541: 
                    542:        i = 0;
                    543:        do {
                    544:            val = dbdma_ld4_endian(&dmap->d_status); eieio();
                    545:            delay(50);
                    546:            i++;
                    547:        } while ((i < 100000) && (val & DBDMA_CNTRL_ACTIVE));
                    548:        if (i == 100000)
                    549:            printf("mace(%s): kdp_mace_tx_dbdma poll timed out 0x%x", msg, val);
                    550:     }
                    551: }
                    552: 
                    553: int
                    554: kdp_mace_recv_pkt(funcptr pktfunc, void * p)
                    555: {
                    556:     vm_offset_t                        address;
                    557:     struct mace_board *                board;
                    558:     long                       bytes;
                    559:     int                                done = 0;
                    560:     int                                doContinue = 0;
                    561:     mace_t *                   m;
                    562:     unsigned long              resid;
                    563:     unsigned short             status;
                    564:     int                                tail;
                    565: 
                    566:     m = &mace;
                    567:     board = m->ereg;
                    568: 
                    569:     /* remember where the tail was */
                    570:     tail = m->rv_tail;
                    571:     for (done = 0; (done == 0) && (m->rv_head != tail);) {
                    572:        dbdma_command_t *       dmaHead;
                    573:        
                    574:        dmaHead = &m->rv_dma[m->rv_head];
                    575:        resid = dbdma_ld4_endian(&dmaHead->d_status_resid);
                    576:        status = (resid >> 16);
                    577:        bytes  = resid & 0xffff;
                    578:        bytes = ETHERNET_BUF_SIZE - bytes - 8; /* strip off FCS/CRC */
                    579: 
                    580:        if ((status & DBDMA_ETHERNET_EOP) == 0)  {
                    581:            /* no packets are ready yet */
                    582:            break;
                    583:        }
                    584:        doContinue = 1;
                    585:        /* if the packet is good, pass it up */
                    586:        if (bytes >= (ETHER_MIN_PACKET - 4)) {
                    587:            char * dmaPacket;
                    588:            dmaPacket = (char *)&m->rv_dma_area[m->rv_head * ETHERNET_BUF_SIZE];
                    589:            done = (*pktfunc)(dmaPacket, bytes, p);
                    590:        }
                    591:        /* mark the head as the new tail in the dma channel command list */
                    592:        DBDMA_BUILD(dmaHead, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_ALWAYS,
                    593:                    DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
                    594:        flush_dcache((vm_offset_t)dmaHead, 
                    595:                sizeof(*dmaHead),
                    596:                FALSE);
                    597:        eieio();
                    598: 
                    599:        /* make the tail an available dma'able entry */
                    600:        {
                    601:            dbdma_command_t *           dmaTail;
                    602:            dmaTail = &m->rv_dma[m->rv_tail];
                    603:            address = kvtophys((vm_offset_t) 
                    604:                               &m->rv_dma_area[m->rv_tail*ETHERNET_BUF_SIZE]);
                    605:            // this command is live so write it carefully
                    606:            DBDMA_ST4_ENDIAN(&dmaTail->d_address, address);
                    607:            dmaTail->d_status_resid = 0;
                    608:            dmaTail->d_cmddep = 0;
                    609:            eieio();
                    610:            DBDMA_ST4_ENDIAN(&dmaTail->d_cmd_count,
                    611:                            ((DBDMA_CMD_IN_LAST) << 28) | ((0) << 24) |
                    612:                            ((DBDMA_INT_ALWAYS) << 20) |
                    613:                            ((DBDMA_BRANCH_NEVER) << 18) | ((DBDMA_WAIT_NEVER) << 16) |
                    614:                            (ETHERNET_BUF_SIZE));
                    615:            eieio();
                    616:            flush_dcache((vm_offset_t)dmaTail, 
                    617:                        sizeof(*dmaTail),
                    618:                        FALSE);
                    619:        }
                    620:        /* head becomes the tail */
                    621:        m->rv_tail = m->rv_head;
                    622: 
                    623:        /* advance the head */
                    624:        m->rv_head++;
                    625:        if (m->rv_head == (ETHER_RX_NUM_DBDMA_BUFS + 1))
                    626:            m->rv_head = 0;
                    627:     }
                    628:     if (doContinue) {
                    629:        sync();
                    630:        dbdma_continue(m->rv_dbdma);
                    631:     }
                    632:     return (done);
                    633: }
                    634: 
                    635: static int
                    636: kdp_mace_copy(char * pktBuf, int len, void * p)
                    637: {
                    638:     struct kdp_mace_copy_desc * cp = (struct kdp_mace_copy_desc *)p;
                    639: 
                    640:     bcopy((char *)pktBuf, (char *)cp->data, len);
                    641:     *cp->len = len;
                    642:     return (1); /* signal that we're done */
                    643: }
                    644: 
                    645: /* kdb debugger routines */
                    646: static void
                    647: polled_send_pkt(char * data, int len)
                    648: {
                    649:     waitForDBDMADone("mace: polled_send_pkt start");
                    650:     kdp_mace_tx_dbdma(data, len);
                    651:     waitForDBDMADone("mace: polled_send_pkt end");
                    652:     return;
                    653: }
                    654: 
                    655: static void
                    656: polled_receive_pkt(char *data, int *len, int timeout_ms)
                    657: {
                    658:     struct kdp_mace_copy_desc cp;
                    659: 
                    660:     cp.len = len;
                    661:     cp.data = data;
                    662: 
                    663:     timeout_ms *= 1000;
                    664:     *len = 0;
                    665:     while (kdp_mace_recv_pkt(kdp_mace_copy, (void *)&cp) == 0) {
                    666:        if (timeout_ms <= 0)
                    667:            break;
                    668:        delay(50);
                    669:        timeout_ms -= 50;
                    670:     }
                    671:     return;
                    672: }

unix.superglobalmegacorp.com

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