Annotation of Gnu-Mach/chips/lance.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1993-1989 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     File:   lance.c
                     28:  *     Author: Robert V. Baron & Alessandro Forin
                     29:  *     Date:   5/90
                     30:  *
                     31:  *     Driver for the DEC LANCE Ethernet Controller.
                     32:  */
                     33: 
                     34: /*
                     35:  
                     36:   Byte ordering issues.
                     37: 
                     38:   The lance sees data naturally as half word (16 bit) quantitites. 
                     39:   Bit 2 (BSWP) in control register 3 (CSR3) controls byte swapping.
                     40:   To quote the spec:
                     41: 
                     42:   02   BSWP    BYTE SWAP allows the chip to 
                     43:                operate in systems that consdier bits (15:08) of data pointers
                     44:                by an even addressa and bits (7:0) to be pointed by an 
                     45:                odd address.
                     46: 
                     47:                When BSWP=1, the chip will swap the high and low bytes on DMA
                     48:                data transfers between the silo and bus memory. Only data from
                     49:                silo transfers is swapped; the Initialization Block data and 
                     50:                the Descriptor Ring entries are NOT swapped. (emphasis theirs)
                     51:   
                     52: 
                     53:   So on systems with BYTE_MSF=1, the BSWP bit should be set. Note,
                     54:   however, that all shorts in the descriptor ring and initialization
                     55:   block need to be swapped. The BITFIELD macros in lance.h handle this
                     56:   magic.
                     57: 
                     58: */
                     59: 
                     60: #include <ln.h>
                     61: #if     NLN > 0
                     62: #include <platforms.h>
                     63: 
                     64: /*
                     65:  * AMD Am7990 LANCE (Ethernet Interface)
                     66:  */
                     67: #include <sys/ioctl.h>
                     68: #include <vm/vm_kern.h>
                     69: 
                     70: #include <machine/machspl.h>           /* spl definitions */
                     71: #include <kern/time_out.h>
                     72: #include <sys/syslog.h>
                     73: #include <ipc/ipc_port.h>
                     74: #include <ipc/ipc_kmsg.h>
                     75: 
                     76: #include <device/device_types.h>
                     77: #include <device/errno.h>
                     78: #include <device/io_req.h>
                     79: #include <device/if_hdr.h>
                     80: #include <device/if_ether.h>
                     81: #include <device/net_status.h>
                     82: #include <device/net_io.h>
                     83: 
                     84: #ifdef FLAMINGO
                     85: #define se_reg_type unsigned int
                     86: #endif
                     87: 
                     88: #include <chips/lance.h>
                     89: #include <chips/busses.h>
                     90: 
                     91: #define private static
                     92: #define public
                     93: 
                     94: typedef struct se_softc *se_softc_t; /* move above prototypes */
                     95: 
                     96: void se_write_reg(); /* forwards */
                     97: void se_read();
                     98: void se_rint();
                     99: void se_tint();
                    100: 
                    101: private vm_offset_t se_Hmem_nogap(), se_Hmem_gap16();
                    102: private vm_offset_t se_malloc();
                    103: 
                    104: 
                    105: /* This config section should go into a separate file */
                    106: 
                    107: #ifdef  LUNA88K
                    108: # include <luna88k/board.h>
                    109: # define MAPPED 1
                    110:   #undef bcopy
                    111:   extern void bcopy(), bzero();
                    112: 
                    113: #define wbflush()
                    114: #define Hmem(lna)      (vm_offset_t)((lna) + sc->lnbuf)
                    115: #define Lmem(lna)      (vm_offset_t)((lna) + sc->lnoffset)
                    116: 
                    117: #define SPACE (TRI_PORT_RAM_SPACE>>1)
                    118: private struct se_switch se_switch[] = {
                    119:        {   LANCE_ADDR - TRI_PORT_RAM,  /* pointer */
                    120:            SPACE /* host side */, 
                    121:            SPACE /* lance side */, 
                    122:            - TRI_PORT_RAM,
                    123:            0, /* romstride */
                    124:            0, /* ramstride */
                    125:            SPACE, 
                    126:            /* desc_copyin */   bcopy,
                    127:            /* desc_copyout */  bcopy,
                    128:            /* data_copyin */   bcopy,
                    129:            /* data_copyout */  bcopy,
                    130:            /* bzero */         bzero,
                    131:            /* mapaddr */       se_Hmem_nogap,
                    132:            /* mapoffs */       se_Hmem_nogap
                    133:       },
                    134: };
                    135: 
                    136: #endif
                    137: 
                    138: #ifdef DECSTATION
                    139: #include <mips/mips_cpu.h>
                    140: #include <mips/PMAX/pmad_aa.h>
                    141: 
                    142: #define        MAPPED 1
                    143: 
                    144: /*
                    145:  * The LANCE buffer memory as seen from the Pmax cpu is funny.
                    146:  * It is viewed as short words (16bits), spaced at word (32bits)
                    147:  * intervals.  The same applies to the registers.  From the LANCE
                    148:  * point of view memory is instead contiguous.
                    149:  * The ROM that contains the station address is in the space belonging
                    150:  * to the clock/battery backup memory.  This space is again 16 bits
                    151:  * in a 32bit envelope.  And the ether address is stored in the "high"
                    152:  * byte of 6 consecutive quantities.
                    153:  *
                    154:  * But Pmaxen and 3maxen (and..) map lance space differently.
                    155:  * This requires dynamic adaptation of the driver, which
                    156:  * is done via the following switches.
                    157:  * For convenience, the switch holds information about
                    158:  * the location of the lance control registers as well.
                    159:  * This could be either absolute (pmax) or relative to
                    160:  * some register base (3max, turbochannel)
                    161:  */
                    162: void copyin_gap16(), copyout_gap16(), bzero_gap16();
                    163: extern void bcopy(), bzero();
                    164: void copyin_gap32(), copyout_gap32();
                    165: 
                    166: private struct se_switch se_switch[] = {
                    167: /* pmax */
                    168:        { 0x00000000, 0x01000000, 0x0, 0x05000000, 8, 16, 64*1024, 
                    169:          copyin_gap16, copyout_gap16, copyin_gap16, copyout_gap16,
                    170:          bzero_gap16, se_Hmem_gap16, se_Hmem_gap16},
                    171: /* 3max */
                    172:        { PMAD_OFFSET_LANCE, PMAD_OFFSET_RAM, PMAD_OFFSET_RAM, PMAD_OFFSET_ROM,
                    173:          16, 0, PMAD_RAM_SIZE,
                    174:          bcopy, bcopy, bcopy, bcopy, bzero, se_Hmem_nogap, se_Hmem_nogap},
                    175: /* 3min */
                    176: /* XXX re-use other 64k */
                    177:        { 0/*later*/, 0/*later*/, 0x0, 0/*later*/, 0, 128, 64*1024,
                    178:          copyin_gap16, copyout_gap16, copyin_gap32, copyout_gap32,
                    179:          bzero_gap16, se_Hmem_gap16, se_Hmem_nogap},
                    180: };
                    181: 
                    182: /*
                    183:  * "lna" is what se_malloc hands back.  They are offsets using
                    184:  * the sizing that the Lance would use. The Lance space is
                    185:  * mapped somewhere in the I/O space, as indicated by the softc.
                    186:  * Hence we have these two macros:
                    187:  */
                    188: /* H & L are not hi and lo but
                    189:    H = HOST  == addresses for host to reference board memory
                    190:    L = LOCAL == addresses on board
                    191:  */
                    192: #define Hmem(lna)      (vm_offset_t)((se_sw->mapaddr)(lna) + sc->lnbuf)
                    193: #define Lmem(lna)      (vm_offset_t)((vm_offset_t)lna + sc->lnoffset)
                    194: #endif /*DECSTATION*/
                    195: 
                    196: 
                    197: #ifdef VAXSTATION
                    198: #include <vax/ka3100.h>
                    199: 
                    200: #define wbflush()
                    201: 
                    202: void xzero(x, l) vm_offset_t x; int l; { blkclr(x, l); }
                    203: void xcopy(f, t, l) vm_offset_t f, t; int l; { bcopy(f, t, l); }
                    204: 
                    205: private struct se_switch se_switch[] = {
                    206:        /* pvax sees contiguous bits in lower 16Meg of memory */
                    207:        { 0, 0, 0, 0, 0, 0, 64*1024,
                    208:          xcopy, xcopy, xcopy, xcopy, xzero, se_Hmem_nogap, se_Hmem_nogap},
                    209: };
                    210: 
                    211: /*
                    212:  * "lna" is what se_malloc hands back.  They are offsets using
                    213:  * the sizing that the Lance would use. The Lance space is
                    214:  * mapped somewhere in the I/O space, as indicated by the softc.
                    215:  * Hence we have these two macros:
                    216:  */
                    217: /* H & L are not hi and lo but
                    218:    H = HOST  == addresses for host to reference board memory
                    219:    L = LOCAL == addresses on board
                    220:  */
                    221:        /*
                    222:         * This does not deal with > 16 Meg physical memory, where
                    223:         * Hmem != Lmem
                    224:         */
                    225: #define Hmem(lna)      (vm_offset_t)((lna) + sc->lnbuf)
                    226: #define Lmem(lna)      (vm_offset_t)((lna) + sc->lnoffset)
                    227: 
                    228: #endif /*VAXSTATION*/
                    229: 
                    230: 
                    231: #ifdef FLAMINGO
                    232: #include <alpha/alpha_cpu.h>
                    233: 
                    234: /* XXX might be wrong, mostly stolen from kmin */
                    235: extern void copyin_gap16(), copyout_gap16(), bzero_gap16();
                    236: extern void copyin_gap32(), copyout_gap32();
                    237: extern void bcopy(), bzero();
                    238: 
                    239: private struct se_switch se_switch[] = {
                    240: /* XXX re-use other 64k */
                    241:        { 0/*later*/, 0/*later*/, 0x0, 0/*later*/, 0, 128, 64*1024,
                    242:          copyin_gap16, copyout_gap16, copyin_gap32, copyout_gap32,
                    243:          bzero_gap16, se_Hmem_gap16, se_Hmem_nogap},
                    244: };
                    245: 
                    246: /*
                    247:  * "lna" is what se_malloc hands back.  They are offsets using
                    248:  * the sizing that the Lance would use. The Lance space is
                    249:  * mapped somewhere in the I/O space, as indicated by the softc.
                    250:  * Hence we have these two macros:
                    251:  */
                    252: /* H & L are not hi and lo but
                    253:    H = HOST  == addresses for host to reference board memory
                    254:    L = LOCAL == addresses on board
                    255:  */
                    256: #define Hmem(lna)      (vm_offset_t)((se_sw->mapaddr)(lna) + sc->lnbuf)
                    257: #define Lmem(lna)      (vm_offset_t)((vm_offset_t)lna + sc->lnoffset)
                    258: #endif /*FLAMINGO*/
                    259: 
                    260: 
                    261: /*
                    262:  * Map a lance-space offset into an host-space one
                    263:  */
                    264: private vm_offset_t se_Hmem_nogap( vm_offset_t lna) { return lna;}
                    265: private vm_offset_t se_Hmem_gap16( vm_offset_t lna) { return lna << 1;}
                    266: 
                    267: /*
                    268:  * Memory addresses for LANCE are 24 bits wide.
                    269:  */
                    270: #define Addr_lo(y)     ((unsigned short)((vm_offset_t)(y) & 0xffff))
                    271: #define        Addr_hi(y)      ((unsigned short)(((vm_offset_t)(y)>>16) & 0xff))
                    272: 
                    273: #define        LN_MEMORY_SIZE  (se_sw->ramsize)
                    274: 
                    275: /* XXX to accomodate heterogeneity this should be made per-drive */
                    276: /* XXX and then some more */
                    277: 
                    278: struct se_switch *se_sw = se_switch;
                    279: 
                    280: void set_se_switch(n)
                    281: int n;
                    282: {
                    283:        se_sw = &se_switch[n];
                    284: }
                    285: 
                    286: #ifndef LUNA88K
                    287: void setse_switch(n, r, b, l, o)
                    288:        vm_offset_t     r, b, l, o;
                    289:        int             n;
                    290: {
                    291:        se_switch[n].regspace = r;
                    292:        se_switch[n].bufspace = b;
                    293:        se_switch[n].ln_bufspace = l;
                    294:        se_switch[n].romspace = o;
                    295: 
                    296:        /* make sure longword aligned */
                    297:        if (se_switch[n].bufspace & 0x7) {
                    298:                se_switch[n].bufspace = (se_switch[n].bufspace+0x7) & ~0x7;
                    299:        }
                    300: 
                    301:        set_se_switch(n);
                    302: }
                    303: #endif
                    304: 
                    305: /*
                    306:  * Autoconf info
                    307:  */
                    308: 
                    309: private vm_offset_t se_std[NLN] = { 0 };
                    310: private struct bus_device *se_info[NLN];
                    311: private int se_probe();
                    312: private void se_attach();
                    313: 
                    314: struct bus_driver se_driver =
                    315:        { se_probe, 0, se_attach, 0, se_std, "se", se_info, };
                    316: 
                    317: /*
                    318:  * Externally visible functions
                    319:  */
                    320: char   *se_unprobed_addr = 0;
                    321: void   se_intr();                              /* kernel */
                    322: 
                    323: int    se_open(), se_output(), se_get_status(),        /* user */
                    324:        se_set_status(), se_setinput(), se_restart();
                    325: 
                    326: /*
                    327:  *
                    328:  * Internal functions & definitions
                    329:  *
                    330:  */
                    331: 
                    332: private        int se_probe();
                    333: private  void se_init();
                    334: private        void init_lance_space();
                    335: private  void se_desc_set_status();
                    336: private  volatile long *se_desc_alloc();       /* must be aligned! */
                    337: void   se_start();
                    338: private        void copy_from_lance();
                    339: private        int copy_to_lance();
                    340: 
                    341: int se_verbose = 0;    /* debug flag */
                    342: 
                    343: #define RLOG   4               /* 2**4 = 16  receive descriptors */
                    344: #define TLOG   4               /* 2**4 = 16  transmit descriptors */
                    345: #define NRCV   (1<<RLOG)       /* Receive descriptors */
                    346: #define NXMT   (1<<TLOG)       /* Transmit descriptors */
                    347: 
                    348: #define        LN_BUFFER_SIZE  (0x800-0x80)
                    349: 
                    350: /*
                    351:  * Ethernet software status per interface.
                    352:  *
                    353:  * Each interface is referenced by a network interface structure,
                    354:  * is_if, which contains the output queue for the interface, its address, ...
                    355:  */
                    356: int se_loopback_hack = 1;
                    357: 
                    358: struct se_softc {
                    359:        struct  ifnet   is_if;          /* generic interface header     */
                    360:        unsigned char   is_addr[6];             /* ethernet hardware address    */
                    361:        unsigned short  pad;
                    362:        se_reg_t                lnregs;         /* Lance registers      */
                    363:        vm_offset_t             lnbuf;          /* Lance memory, Host offset */
                    364:        vm_offset_t             lnoffset;       /* Lance memory, Lance offset */
                    365:        vm_offset_t             lnrom;
                    366:        vm_offset_t             lnsbrk;         /* Lance memory allocator */
                    367:        vm_offset_t             lninit_block;   /* Init block address   */
                    368:        se_desc_t               lnrring[NRCV];  /* Receive  ring desc. */
                    369:        volatile long           *lnrbuf[NRCV];  /* Receive  buffers */
                    370:        se_desc_t               lntring[NXMT];  /* Transmit ring desc. */
                    371:        volatile long           *lntbuf[NXMT];  /* Transmit buffers */
                    372: 
                    373:        int     rcv_last;               /* Rcv buffer last read         */
                    374: 
                    375:        io_req_t tpkt[NXMT+1];          /* Xmt pkt queue                */
                    376:        int     xmt_count;              /* Xmt queue size               */
                    377:        int     xmt_last;               /* Xmt queue head (insert)      */
                    378:        int     xmt_complete;           /* Xmt queue tail (remove)      */
                    379: 
                    380:        int     se_flags;               /* Flags for SIOCSIFFLAGS       */
                    381:        int     counters[4];            /* error counters */
                    382: #define bablcnt  counters[0]
                    383: #define misscnt  counters[1]
                    384: #define merrcnt  counters[2]
                    385: #define rstrtcnt counters[3]
                    386: } se_softc_data[NLN];
                    387: 
                    388: se_softc_t     se_softc[NLN];          /* quick access */
                    389: 
                    390: /*
                    391:  * Probe the Lance to see if it's there
                    392:  */
                    393: private int se_open_state = 0;
                    394: 
                    395: private int se_probe(
                    396:        vm_offset_t reg,
                    397:        register struct bus_device *ui)
                    398: {
                    399:        register se_softc_t sc;
                    400:        se_reg_t        rdp, rap;
                    401:        int             unit = ui->unit;
                    402: 
                    403:        /*
                    404:         * See if the interface is there by reading the lance CSR.  On pmaxen
                    405:         * and 3maxen this is superfluous, but.. 
                    406:         */
                    407:        rdp = (se_reg_t) (reg + se_sw->regspace);
                    408: #ifdef DECSTATION
                    409:        if (check_memory(rdp, 0))
                    410:                return 0;
                    411: #endif /*DECSTATION*/
                    412: #ifdef MAPPED
                    413:        SE_probe(reg,ui);
                    414: #endif /*MAPPED*/
                    415:        rap = rdp + 2;          /* XXX might not be true in the future XXX */
                    416:                                /* rdp and rap are "shorts" on consecutive
                    417:                                   "long" word boundaries */
                    418: 
                    419:        /*
                    420:         * Bind this interface to the softc. 
                    421:         */
                    422:        sc = &se_softc_data[unit];
                    423:        se_softc[unit] = sc;
                    424:        sc->lnregs      = (se_reg_t) (reg + se_sw->regspace);
                    425:        sc->lnbuf       = (vm_offset_t) (reg + se_sw->bufspace);
                    426:        sc->lnoffset    = (vm_offset_t) (se_sw->ln_bufspace);
                    427:        sc->lnrom       = (vm_offset_t) (reg + se_sw->romspace);
                    428: 
                    429:        /*
                    430:         * Reset the interface, and make sure we really do it! (the 3max
                    431:         * seems quite stubborn about these registers) 
                    432:         */
                    433:        se_write_reg(rap, CSR0_SELECT, CSR0_SELECT, "RAP");
                    434:        se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
                    435: 
                    436:        /*
                    437:         * Allocate lance RAM buffer memory 
                    438:         */
                    439:        init_lance_space(sc);
                    440: 
                    441:        /*
                    442:         * Initialize the chip
                    443:         *
                    444:         * NOTE: From now on we will only touch csr0
                    445:         */
                    446:        if (se_ship_init_block(sc, unit))
                    447:                return 0;
                    448: 
                    449:        /*
                    450:         * Tell the world we are alive and well 
                    451:         */
                    452:        se_open_state++;
                    453:        return 1;
                    454: }
                    455: 
                    456: int se_ship_init_block(
                    457:        register se_softc_t sc,
                    458:        int             unit)
                    459: {
                    460:        se_reg_t        rdp = sc->lnregs;
                    461:        se_reg_t        rap;
                    462:        register int    i = 0;
                    463: 
                    464:        rap = rdp + 2;          /* XXX might not be true in the future XXX */
                    465: 
                    466:        /*
                    467:         * Load LANCE control block. 
                    468:         */
                    469: 
                    470: #ifdef LUNA88K
                    471:        /* turn on byte swap bit in csr3, set bcon bit - as in 2.5 */
                    472:        se_write_reg(rap, CSR3_SELECT, CSR3_SELECT, "RAP");
                    473:        se_write_reg(rdp, LN_CSR3_BSWP|LN_CSR3_BCON, 
                    474:                          LN_CSR3_BSWP|LN_CSR3_BCON, "csr3"); 
                    475: #endif
                    476:        
                    477:        se_write_reg(rap, CSR1_SELECT, CSR1_SELECT, "RAP");
                    478:        se_write_reg(rdp, Addr_lo(Lmem(sc->lninit_block)),
                    479:                     Addr_lo(Lmem(sc->lninit_block)), "csr1");
                    480: 
                    481:        se_write_reg(rap, CSR2_SELECT, CSR2_SELECT, "RAP");
                    482:        se_write_reg(rdp, Addr_hi(Lmem(sc->lninit_block)),
                    483:                     Addr_hi(Lmem(sc->lninit_block)), "csr2");
                    484: 
                    485:        /*
                    486:         * Start the INIT sequence now
                    487:         */
                    488:        se_write_reg(rap, CSR0_SELECT, CSR0_SELECT, "RAP");
                    489:        *rdp = (LN_CSR0_IDON | LN_CSR0_INIT);
                    490:        wbflush();
                    491: 
                    492:        /* give it plenty of time to settle */
                    493:        while (i++ < 10000) {
                    494:                delay(100);
                    495:                if ((*rdp & LN_CSR0_IDON) != 0)
                    496:                        break;
                    497:        }
                    498:        /* make sure got out okay */
                    499:        if ((*rdp & LN_CSR0_IDON) == 0) {
                    500:                printf("se%d: cannot initialize\n", unit);
                    501:                if (*rdp & LN_CSR0_ERR)
                    502:                        printf("se%d: initialization error, csr = %04x\n",
                    503:                               unit, (*rdp & 0xffff));
                    504:                return 1;
                    505:        }
                    506:        /*
                    507:         * Do not enable interrupts just yet. 
                    508:         */
                    509:        /* se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0"); */
                    510: 
                    511:        return 0;
                    512: }
                    513:  
                    514: void
                    515: se_write_reg(
                    516:        register se_reg_t       regptr,
                    517:        register int            val,
                    518:        register int            result,
                    519:        char                    *regname)
                    520: {
                    521:        register int    i = 0;
                    522: 
                    523:        while ((unsigned short)(*regptr) != (unsigned short)result) {
                    524:                *regptr = (se_reg_type)val;
                    525:                wbflush();
                    526:                if (++i > 10000) {
                    527:                        printf("se: %s did not settle (to x%x): x%x\n",
                    528:                               regname, result, (unsigned short)(*regptr));
                    529:                        return;
                    530:                }
                    531:                delay(100);
                    532:        }
                    533: }
                    534: 
                    535: unsigned short
                    536: se_read_reg(
                    537:        register se_reg_t regptr)
                    538: {
                    539:        return (unsigned short) (*regptr);
                    540: }
                    541: 
                    542: private void
                    543: init_lance_space(
                    544:        register se_softc_t sc)
                    545: {
                    546:        register int    lptr;                   /* Generic lance pointer */
                    547:        se_desc_t       ringaddr;
                    548:        long           *rom_eaddress = (long *) sc->lnrom;
                    549:        int             i;
                    550:        struct se_init_block    init_block;
                    551: 
                    552:        /*
                    553:         * Allocate local RAM buffer memory for the init block,
                    554:         * fill in our local copy then copyout.
                    555:         */
                    556: 
                    557:        sc->lninit_block = se_malloc(sc, sizeof (struct se_init_block));
                    558: 
                    559:        /*
                    560:         * Set values on stack, then copyout en-masse
                    561:         */
                    562:        bzero(&init_block, sizeof(init_block));
                    563:        init_block.mode = 0;
                    564: 
                    565:        /* byte swapping between host and lance */
                    566: 
                    567:        init_block.phys_addr_low = ((rom_eaddress[0]>>se_sw->romstride)&0xff) |
                    568:                              (((rom_eaddress[1]>>se_sw->romstride)&0xff) << 8);
                    569:        init_block.phys_addr_med = ((rom_eaddress[2]>>se_sw->romstride)&0xff) |
                    570:                              (((rom_eaddress[3]>>se_sw->romstride)&0xff) << 8);
                    571:        init_block.phys_addr_high = ((rom_eaddress[4]>>se_sw->romstride)&0xff) |
                    572:                              (((rom_eaddress[5]>>se_sw->romstride)&0xff) << 8);
                    573: 
                    574:        /*
                    575:         * Allocate both descriptor rings at once.
                    576:         * Note that the quadword alignment requirement is
                    577:         * inherent in the way we perform allocation,
                    578:         * but it does depend on the size of the init block.
                    579:         */
                    580:        lptr = se_malloc(sc, sizeof (struct se_desc) * (NXMT + NRCV));
                    581: 
                    582:        /*
                    583:         * Initialize the buffer descriptors
                    584:         */
                    585:        init_block.recv_ring_pointer_lo = Addr_lo(Lmem(lptr));
                    586:        init_block.recv_ring_pointer_hi = Addr_hi(Lmem(lptr));
                    587:        init_block.recv_ring_len = RLOG;
                    588: 
                    589:        for ( i = 0; i < NRCV ; i++, lptr += sizeof(struct se_desc)) {
                    590:                ringaddr = (se_desc_t)Hmem(lptr);
                    591:                sc->lnrring[i] = ringaddr;
                    592:                sc->lnrbuf[i] = se_desc_alloc (sc, ringaddr);
                    593:        }
                    594: 
                    595:        init_block.xmit_ring_pointer_lo = Addr_lo(Lmem(lptr));
                    596:        init_block.xmit_ring_pointer_hi = Addr_hi(Lmem(lptr));
                    597:        init_block.xmit_ring_len = TLOG;
                    598: 
                    599:        for ( i = 0 ; i < NXMT ; i++, lptr += sizeof(struct se_desc)) {
                    600:                ringaddr = (se_desc_t)Hmem(lptr);
                    601:                sc->lntring[i] = ringaddr;
                    602:                sc->lntbuf[i] = se_desc_alloc (sc, ringaddr);
                    603:        }
                    604: 
                    605:        /*
                    606:         * No logical address filtering
                    607:         */
                    608:        init_block.logical_addr_filter0 = 0;
                    609:        init_block.logical_addr_filter1 = 0;
                    610:        init_block.logical_addr_filter2 = 0;
                    611:        init_block.logical_addr_filter3 = 0;
                    612: 
                    613:        /*
                    614:         * Move init block into lance space
                    615:         */
                    616:        (se_sw->desc_copyout)((vm_offset_t)&init_block, Hmem(sc->lninit_block), sizeof(init_block));
                    617:        wbflush();
                    618: }
                    619: 
                    620: /*
                    621:  * Interface exists: make available by filling in network interface
                    622:  * record.  System will initialize the interface when it is ready
                    623:  * to accept packets.
                    624:  */
                    625: private void
                    626: se_attach(
                    627:        register struct bus_device *ui)
                    628: {
                    629:        unsigned char         *enaddr;
                    630:        struct ifnet   *ifp;
                    631:        long           *rom_eaddress;
                    632:        int             unit = ui->unit;
                    633:        se_softc_t      sc = se_softc[unit];
                    634: 
                    635:        rom_eaddress = (long *) sc->lnrom;
                    636: 
                    637:        /*
                    638:         * Read the address from the prom and save it. 
                    639:         */
                    640:        enaddr = sc->is_addr;
                    641:        enaddr[0] = (unsigned char) ((rom_eaddress[0] >> se_sw->romstride) & 0xff);
                    642:        enaddr[1] = (unsigned char) ((rom_eaddress[1] >> se_sw->romstride) & 0xff);
                    643:        enaddr[2] = (unsigned char) ((rom_eaddress[2] >> se_sw->romstride) & 0xff);
                    644:        enaddr[3] = (unsigned char) ((rom_eaddress[3] >> se_sw->romstride) & 0xff);
                    645:        enaddr[4] = (unsigned char) ((rom_eaddress[4] >> se_sw->romstride) & 0xff);
                    646:        enaddr[5] = (unsigned char) ((rom_eaddress[5] >> se_sw->romstride) & 0xff);
                    647: 
                    648:        printf(": %x-%x-%x-%x-%x-%x",
                    649:               (rom_eaddress[0] >> se_sw->romstride) & 0xff,
                    650:               (rom_eaddress[1] >> se_sw->romstride) & 0xff,
                    651:               (rom_eaddress[2] >> se_sw->romstride) & 0xff,
                    652:               (rom_eaddress[3] >> se_sw->romstride) & 0xff,
                    653:               (rom_eaddress[4] >> se_sw->romstride) & 0xff,
                    654:               (rom_eaddress[5] >> se_sw->romstride) & 0xff);
                    655: 
                    656:        /*
                    657:         * Initialize the standard interface descriptor 
                    658:         */
                    659:        ifp = &sc->is_if;
                    660:        ifp->if_unit = unit;
                    661:        ifp->if_header_size = sizeof(struct ether_header);
                    662:        ifp->if_header_format = HDR_ETHERNET;
                    663:        ifp->if_address_size = 6;
                    664:        ifp->if_mtu = ETHERMTU;
                    665:        ifp->if_flags |= IFF_BROADCAST;
                    666: 
                    667:        ifp->if_address = (char *) enaddr;
                    668: 
                    669:        if_init_queues(ifp);
                    670: #ifdef MAPPED
                    671:        SE_attach(ui);
                    672: #endif /*MAPPED*/
                    673: 
                    674: }
                    675: 
                    676: /*
                    677:  * Use a different hardware address for interface
                    678:  */
                    679: void
                    680: se_setaddr(
                    681:        unsigned char   eaddr[6],
                    682:        int             unit)
                    683: {
                    684:        register se_softc_t sc = se_softc[unit];
                    685:        struct se_init_block    init_block;
                    686: 
                    687:        /*
                    688:         * Modify initialization block accordingly
                    689:         */
                    690:        (se_sw->desc_copyin) (Hmem(sc->lninit_block), (vm_offset_t)&init_block, sizeof(init_block));
                    691:        bcopy(eaddr, &init_block.phys_addr_low, sizeof(*eaddr));
                    692:        (se_sw->desc_copyout)((vm_offset_t)&init_block, Hmem(sc->lninit_block), sizeof(init_block));
                    693:        /*
                    694:         * Make a note of it
                    695:         */
                    696:        bcopy(eaddr, sc->is_addr, sizeof(*eaddr));
                    697: 
                    698:        /*
                    699:         * Restart the interface
                    700:         */
                    701:        se_restart(&sc->is_if);
                    702:        se_init(unit);
                    703: }
                    704: 
                    705: /*
                    706:  * Restart interface
                    707:  *
                    708:  * We use this internally on those errors that hang the chip,
                    709:  * not sure yet what use the MI code will make of it.
                    710:  *
                    711:  * After stopping the chip and effectively turning off the interface
                    712:  * we release all pending buffers and cause the chip to init
                    713:  * itself.  We do not enable interrupts here.
                    714:  */
                    715: int
                    716: se_restart( register struct ifnet *ifp )
                    717: {
                    718:        register se_softc_t sc = se_softc[ifp->if_unit];
                    719:        se_reg_t        rdp;
                    720:        register int    i;
                    721: 
                    722:        rdp = sc->lnregs;
                    723: 
                    724:        /*
                    725:         * stop the chip 
                    726:         */
                    727:        se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
                    728: 
                    729:        /*
                    730:         * stop network activity 
                    731:         */
                    732:        if (ifp->if_flags & IFF_RUNNING) {
                    733:                ifp->if_flags &= ~(IFF_UP | IFF_RUNNING);
                    734:                sc->se_flags &= ~(IFF_UP | IFF_RUNNING);
                    735:        }
                    736:        sc->rstrtcnt++;
                    737: 
                    738:        if (se_verbose)
                    739:                printf("se%d: %d restarts\n", ifp->if_unit, sc->rstrtcnt);
                    740: 
                    741:        /*
                    742:         * free up any buffers currently in use 
                    743:         */
                    744:        for (i = 0; i < NXMT; i++)
                    745:                if (sc->tpkt[i]) {
                    746:                        iodone(sc->tpkt[i]);
                    747:                        sc->tpkt[i] = (io_req_t) 0;
                    748:                }
                    749:        /*
                    750:         * INIT the chip again, no need to reload init block address. 
                    751:         */
                    752:        se_ship_init_block(sc, ifp->if_unit);
                    753: 
                    754:        return (0);
                    755: }
                    756: 
                    757: /*
                    758:  * Initialize the interface.
                    759:  */
                    760: private void
                    761: se_init( int unit )
                    762: {
                    763:        register se_softc_t      sc = se_softc[unit];
                    764:        register se_desc_t      *rp;
                    765:        register struct ifnet   *ifp = &sc->is_if;
                    766:        se_reg_t        rdp;
                    767:        short           mode;
                    768:        spl_t           s;
                    769:        int             i;
                    770: 
                    771:        if (ifp->if_flags & IFF_RUNNING)
                    772:                return;
                    773: 
                    774:        rdp = sc->lnregs;
                    775: 
                    776:        /*
                    777:         * Init the buffer descriptors and indexes for each of the rings. 
                    778:         */
                    779:        for (i = 0, rp = sc->lnrring; i < NRCV; i++, rp++)
                    780:                se_desc_set_status(*rp, LN_RSTATE_OWN);
                    781: 
                    782:        for (i = 0, rp = sc->lntring; i < NXMT; i++, rp++)
                    783:                se_desc_set_status(*rp, 0);
                    784: 
                    785:        sc->xmt_count = sc->xmt_complete = sc->xmt_last = sc->rcv_last = 0;
                    786: 
                    787:        /*
                    788:         * Deal with loopback mode operation 
                    789:         */
                    790:        s = splimp();
                    791: 
                    792:        (se_sw->desc_copyin) (Hmem(sc->lninit_block), (vm_offset_t)&mode, sizeof(mode));
                    793: 
                    794:        if (ifp->if_flags & IFF_LOOPBACK
                    795:            && ((mode & LN_MODE_LOOP) == 0)) {
                    796:                /* if not already in loopback mode, do external loopback */
                    797:                mode &= ~LN_MODE_INTL;
                    798:                mode |= LN_MODE_LOOP;
                    799:                (se_sw->desc_copyout) ((vm_offset_t)&mode, Hmem(sc->lninit_block), sizeof(mode));
                    800:                se_restart(ifp);
                    801:                se_init(ifp->if_unit);
                    802:                splx(s);
                    803:                return;
                    804:        }
                    805: 
                    806:        ifp->if_flags |= (IFF_UP | IFF_RUNNING);
                    807:        sc->se_flags |= (IFF_UP | IFF_RUNNING);
                    808: 
                    809:        /*
                    810:         * Start the Lance and enable interrupts 
                    811:         */
                    812:        *rdp = (LN_CSR0_STRT | LN_CSR0_INEA);
                    813:        wbflush();
                    814: 
                    815:        /*
                    816:         * See if anything is already queued 
                    817:         */
                    818:        se_start(unit);
                    819:        splx(s);
                    820: }
                    821: 
                    822: 
                    823: /*
                    824:  * Shut off the lance
                    825:  */
                    826: void
                    827: se_stop(int unit)
                    828: {
                    829:        se_reg_t        rdp = se_softc[unit]->lnregs;
                    830: 
                    831:        se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
                    832: }
                    833: 
                    834: 
                    835: /*
                    836:  * Open the device, declaring the interface up
                    837:  * and enabling lance interrupts.
                    838:  */
                    839: /*ARGSUSED*/
                    840: int
                    841: se_open(
                    842:        int     unit,
                    843:        int     flag)
                    844: {
                    845:        register se_softc_t     sc = se_softc[unit];
                    846: 
                    847:        if (unit >= NLN)
                    848:                return EINVAL;
                    849:        if (!se_open_state)
                    850:                return ENXIO;
                    851: 
                    852:        sc->is_if.if_flags |= IFF_UP;
                    853:        se_open_state++;
                    854:        se_init(unit);
                    855:        return (0);
                    856: }
                    857: 
                    858: #ifdef MAPPED
                    859: int se_use_mapped_interface[NLN];
                    860: #endif /*MAPPED*/
                    861: 
                    862: void
                    863: se_normal(int unit)
                    864: {
                    865: #ifdef MAPPED
                    866:        se_use_mapped_interface[unit] = 0;
                    867: #endif /*MAPPED*/
                    868:        if (se_softc[unit]) {
                    869:                se_restart((struct ifnet *)se_softc[unit]);
                    870:                se_init(unit);
                    871:        }
                    872: }
                    873: 
                    874: /*
                    875:  * Ethernet interface interrupt routine
                    876:  */
                    877: void
                    878: se_intr(
                    879:        int     unit,
                    880:        spl_t   spllevel)
                    881: {
                    882:        register se_softc_t      sc = se_softc[unit];
                    883:        se_reg_t                 rdp;
                    884:        register struct ifnet   *ifp = &sc->is_if;
                    885:        register unsigned short  csr;
                    886: 
                    887: #ifdef MAPPED
                    888:        if (se_use_mapped_interface[unit])
                    889:        {
                    890:                SE_intr(unit,spllevel);
                    891:                return;
                    892:        }
                    893: #endif /*MAPPED*/
                    894: 
                    895:        if (se_open_state < 2) { /* Stray, or not open for business */
                    896:                rdp = (sc ? sc->lnregs : (se_reg_t)se_unprobed_addr);
                    897:                *rdp |= LN_CSR0_STOP;
                    898:                wbflush();
                    899:                return;
                    900:        }
                    901:        rdp = sc->lnregs;
                    902: 
                    903:        /*
                    904:         * Read the CSR and process any error condition.
                    905:         * Later on, restart the lance by writing back
                    906:         * the CSR (for set-to-clear bits).
                    907:         */
                    908:        csr = *rdp;             /* pick up the csr */
                    909: 
                    910:        /* drop spurious interrupts */
                    911:        if ((csr & LN_CSR0_INTR) == 0)
                    912:          return;
                    913: 
                    914: #ifdef DECSTATION
                    915:        splx(spllevel); /* drop priority now */
                    916: #endif /*DECSTATION*/
                    917: again:
                    918:        /*
                    919:         * Check for errors first
                    920:         */
                    921:        if ( csr & LN_CSR0_ERR ) {
                    922:                if (csr & LN_CSR0_MISS) {
                    923:                        /*
                    924:                         * Stop the chip to prevent a corrupt packet from
                    925:                         * being transmitted.  There is a known problem with
                    926:                         * missed packet errors causing corrupted data to
                    927:                         * be transmitted to the same host as was just
                    928:                         * transmitted, with a valid crc appended to the
                    929:                         * packet.  The only solution is to stop the chip,
                    930:                         * which will clear the Lance silo, thus preventing
                    931:                         * the corrupt data from being sent.
                    932:                         */
                    933:                        se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
                    934: 
                    935:                        sc->misscnt++;
                    936:                        if (se_verbose) {
                    937:                                int me = 0, lance = 0, index;
                    938:                                struct se_desc r;
                    939:                                for (index = 0; index < NRCV; index++) {
                    940:                                        (se_sw->desc_copyin)(
                    941:                                            (vm_offset_t)sc->lnrring[index],
                    942:                                            (vm_offset_t)&r,
                    943:                                            sizeof(r));
                    944:                                        if (r.status & LN_RSTATE_OWN)
                    945:                                                lance++;
                    946:                                        else
                    947:                                                me++;
                    948:                                }
                    949:                                printf("se%d: missed packet (%d) csr = %x, Lance %x, me %x\n",
                    950:                                        unit, sc->misscnt, csr, lance, me);
                    951:                        }
                    952:                        se_restart(ifp);
                    953:                        se_init(unit);
                    954:                        return;
                    955:                }
                    956:                if (csr & LN_CSR0_BABL) {
                    957:                        sc->bablcnt++;
                    958:                        if (se_verbose)
                    959:                            printf("se%d: xmt timeout (%d)\n",
                    960:                                   unit, sc->bablcnt);
                    961:                }
                    962:                if (csr & LN_CSR0_MERR) {
                    963:                        sc->merrcnt++;
                    964:                        printf("se%d: memory error (%d)\n",
                    965:                                   unit, sc->merrcnt);
                    966: 
                    967:                        if (((csr & LN_CSR0_RXON) == 0)
                    968:                            || ((csr & LN_CSR0_TXON) == 0)) {
                    969:                                se_restart(ifp);
                    970:                                se_init(unit);
                    971:                                return;
                    972:                        }
                    973:                }
                    974:        }
                    975: 
                    976:        *rdp = LN_CSR0_INEA | (csr & LN_CSR0_WTC);
                    977:        wbflush();
                    978: 
                    979:        if ( csr & LN_CSR0_RINT )
                    980:                se_rint( unit );
                    981: 
                    982:        if ( csr & LN_CSR0_TINT )
                    983:                se_tint( unit );
                    984: 
                    985:        if ((csr = *rdp) & (LN_CSR0_RINT | LN_CSR0_TINT))
                    986:                goto again;
                    987: }
                    988:  
                    989: /*
                    990:  * Handle a transmitter complete interrupt.
                    991:  */
                    992: void
                    993: se_tint(int unit)
                    994: {
                    995:        register se_softc_t sc = se_softc[unit];
                    996:        register        index;
                    997:        register        status;
                    998:        io_req_t        request;
                    999:        struct se_desc  r;
                   1000: 
                   1001:        /*
                   1002:         * Free up descriptors for all packets in queue for which
                   1003:         * transmission is complete.  Start from queue tail, stop at first
                   1004:         * descriptor we do not OWN, or which is in an inconsistent state
                   1005:         * (lance still working). 
                   1006:         */
                   1007: 
                   1008:        while ((sc->xmt_complete != sc->xmt_last) && (sc->xmt_count > 0)) {
                   1009: 
                   1010:                index = sc->xmt_complete;
                   1011:                (se_sw->desc_copyin) ((vm_offset_t)sc->lntring[index],
                   1012:                                      (vm_offset_t)&r, sizeof(r));
                   1013:                status = r.status;
                   1014: 
                   1015:                /*
                   1016:                 * Does lance still own it ? 
                   1017:                 */
                   1018:                if (status & LN_TSTATE_OWN)
                   1019:                        break;
                   1020: 
                   1021:                /*
                   1022:                 * Packet sent allright, release queue slot.
                   1023:                 */
                   1024:                request = sc->tpkt[index];
                   1025:                sc->tpkt[index] = (io_req_t) 0;
                   1026:                sc->xmt_complete = ++index & (NXMT - 1);
                   1027:                --sc->xmt_count;
                   1028: 
                   1029:                sc->is_if.if_opackets++;
                   1030:                if (status & (LN_TSTATE_DEF|LN_TSTATE_ONE|LN_TSTATE_MORE))
                   1031:                        sc->is_if.if_collisions++;
                   1032: 
                   1033:                /*
                   1034:                 * Check for transmission errors. 
                   1035:                 */
                   1036:                if (!se_loopback_hack && status & LN_TSTATE_ERR) {
                   1037:                        sc->is_if.if_oerrors++;
                   1038:                        if (se_verbose)
                   1039:                                printf("se%d: xmt error (x%x)\n", unit, r.status2);
                   1040: 
                   1041:                        if (r.status2 & (LN_TSTATE2_RTRY|LN_TSTATE2_LCOL))
                   1042:                                sc->is_if.if_collisions++;
                   1043: 
                   1044:                        /*
                   1045:                         * Restart chip on errors that disable the
                   1046:                         * transmitter. 
                   1047:                         */
                   1048:                        iodone(request);
                   1049:                        if (r.status2 & LN_TSTATE2_DISABLE) {
                   1050:                                register struct ifnet *ifp = &sc->is_if;
                   1051:                                se_restart(ifp);
                   1052:                                se_init(ifp->if_unit);
                   1053:                                return;
                   1054:                        }
                   1055:                } else if (request) {
                   1056:                        /*
                   1057:                         * If this was a broadcast packet loop it back.
                   1058:                         * Signal successful transmission of the packet. 
                   1059:                         */
                   1060:                        register struct ether_header *eh;
                   1061:                        register int    i;
                   1062: 
                   1063:                        eh = (struct ether_header *) request->io_data;
                   1064:                        /* ether broadcast address is in the spec */
                   1065:                        for (i = 0; (i < 6) && (eh->ether_dhost[i] == 0xff); i++)
                   1066:                                ; /* nop */
                   1067:                        /* sending to ourselves makes sense sometimes */
                   1068:                        if (i != 6 && se_loopback_hack)
                   1069:                                for (i = 0;
                   1070:                                     (i < 6) && (eh->ether_dhost[i] == sc->is_addr[i]);
                   1071:                                     i++)
                   1072:                                ; /* nop */
                   1073:                        if (i == 6)
                   1074:                                se_read(sc, 0, request->io_count, request);
                   1075:                        iodone(request);
                   1076:                }
                   1077:        }
                   1078:        /*
                   1079:         * Dequeue next transmit request, if any. 
                   1080:         */
                   1081:        if (sc->xmt_count <= 0)
                   1082:                se_start(unit);
                   1083: }
                   1084:  
                   1085: /*
                   1086:  * Handle a receiver complete interrupt.
                   1087:  */
                   1088: void
                   1089: se_rint(int unit)
                   1090: {
                   1091:        register se_softc_t     sc = se_softc[unit];
                   1092:        register        index, first, len;
                   1093:        unsigned char          status, status1;
                   1094:        int             ring_cnt;
                   1095:        struct se_desc  r;
                   1096: 
                   1097:        /*
                   1098:         * Starting from where we left off, look around the receive ring and
                   1099:         * pass on all complete packets. 
                   1100:         */
                   1101: 
                   1102:        for (;; sc->rcv_last = ++index & (NRCV - 1)) {
                   1103: 
                   1104:                /*
                   1105:                 * Read in current descriptor 
                   1106:                 */
                   1107: read_descriptor:
                   1108:                (se_sw->desc_copyin) ((vm_offset_t)sc->lnrring[sc->rcv_last],
                   1109:                                      (vm_offset_t)&r, sizeof(r));
                   1110:                status = r.status;
                   1111:                if (status & LN_RSTATE_OWN)
                   1112:                        break;
                   1113:                first = index = sc->rcv_last;
                   1114: 
                   1115:                /*
                   1116:                 * If not the start of a packet, error 
                   1117:                 */
                   1118:                if (!(status & LN_RSTATE_STP)) {
                   1119:                    if (se_verbose)
                   1120:                            printf("se%d: Rring #%d, status=%x !STP\n",
                   1121:                                   unit, index, status);
                   1122:                        break;
                   1123:                }
                   1124:                /*
                   1125:                 * See if packet is chained (should not) by looking at
                   1126:                 * the last descriptor (OWN clear and ENP set).
                   1127:                 * Remember the status info in this last descriptor. 
                   1128:                 */
                   1129:                ring_cnt = 1, status1 = status;
                   1130:                while (((status1 & (LN_RSTATE_ERR | LN_RSTATE_OWN | LN_RSTATE_ENP)) == 0) &&
                   1131:                       (ring_cnt++ <= NRCV)) {
                   1132:                        struct se_desc  r1;
                   1133:                        index = (index + 1) & (NRCV - 1);
                   1134:                        (se_sw->desc_copyin) ((vm_offset_t)sc->lnrring[index],
                   1135:                                              (vm_offset_t)&r1, sizeof(r1));
                   1136:                        status1 = r1.status;
                   1137:                }
                   1138: 
                   1139:                /*
                   1140:                 * Chained packet (--> illegally sized!); re-init the
                   1141:                 * descriptors involved and ignore this bogus packet.  I
                   1142:                 * donno how, but it really happens that we get these
                   1143:                 * monsters. 
                   1144:                 */
                   1145:                if (ring_cnt > 1) {
                   1146:                        /*
                   1147:                         * Return all descriptors to lance 
                   1148:                         */
                   1149:                        se_desc_set_status(sc->lnrring[first], LN_RSTATE_OWN);
                   1150:                        while (first != index) {
                   1151:                                first = (first + 1) & (NRCV - 1);
                   1152:                                se_desc_set_status(sc->lnrring[first], LN_RSTATE_OWN);
                   1153:                        }
                   1154:                        if ((status1 & LN_RSTATE_ERR) && se_verbose)
                   1155:                                printf("se%d: rcv error %x (chained)\n", unit, status1);
                   1156:                        continue;
                   1157:                }
                   1158: 
                   1159:                /*
                   1160:                 * Good packets must be owned by us and have the end of
                   1161:                 * packet flag.  And nothing else. 
                   1162:                 */
                   1163:                if ((status & ~LN_RSTATE_STP) == LN_RSTATE_ENP) {
                   1164:                        sc->is_if.if_ipackets++;
                   1165: 
                   1166:                        if ((len = r.message_size) == 0)
                   1167:                                /* race seen on pmaxen: the lance
                   1168:                                 * has not updated the size yet ??
                   1169:                                 */
                   1170:                                goto read_descriptor;
                   1171:                        /*
                   1172:                         * Drop trailing CRC bytes from len and ship packet
                   1173:                         * up 
                   1174:                         */
                   1175:                        se_read(sc, (volatile char*)sc->lnrbuf[first], len-4,0);
                   1176: 
                   1177:                        /*
                   1178:                         * Return descriptor to lance, and move on to next
                   1179:                         * packet 
                   1180:                         */
                   1181:                        r.status = LN_RSTATE_OWN;
                   1182:                        (se_sw->desc_copyout)((vm_offset_t)&r,
                   1183:                                              (vm_offset_t)sc->lnrring[first],
                   1184:                                              sizeof(r));
                   1185:                        continue;
                   1186:                }
                   1187:                /*
                   1188:                 * Not a good packet, see what is wrong 
                   1189:                 */
                   1190:                if (status & LN_RSTATE_ERR) {
                   1191:                        sc->is_if.if_ierrors++;
                   1192: 
                   1193:                        if (se_verbose)
                   1194:                                printf("se%d: rcv error (x%x)\n", unit, status);
                   1195: 
                   1196:                        /*
                   1197:                         * Return descriptor to lance 
                   1198:                         */
                   1199:                        se_desc_set_status(sc->lnrring[first], LN_RSTATE_OWN);
                   1200:                } else {
                   1201:                        /*
                   1202:                         * Race condition viz lance, Wait for the next
                   1203:                         * interrupt. 
                   1204:                         */
                   1205:                        return;
                   1206:                }
                   1207:        }
                   1208: }
                   1209: 
                   1210: /*
                   1211:  * Output routine.
                   1212:  * Call common function for wiring memory,
                   1213:  * come back later (to se_start) to get
                   1214:  * things going.
                   1215:  */
                   1216: io_return_t
                   1217: se_output(
                   1218:        int             dev,
                   1219:        io_req_t        ior)
                   1220: {
                   1221:     return net_write(&se_softc[dev]->is_if, (int(*)())se_start, ior);
                   1222: }
                   1223:  
                   1224: /*
                   1225:  * Start output on interface.
                   1226:  *
                   1227:  */
                   1228: void
                   1229: se_start(int   unit)
                   1230: {
                   1231:        register se_softc_t sc = se_softc[unit];
                   1232:        io_req_t        request;
                   1233:        struct se_desc  r;
                   1234:        int             tlen;
                   1235:        spl_t           s;
                   1236:        register int    index;
                   1237: 
                   1238:        s = splimp();
                   1239: 
                   1240:        for (index = sc->xmt_last;
                   1241:             sc->xmt_count < (NXMT - 1);
                   1242:             sc->xmt_last = index = (index + 1) & (NXMT - 1)) {
                   1243:                /*
                   1244:                 * Dequeue the next transmit request, if any. 
                   1245:                 */
                   1246:                IF_DEQUEUE(&sc->is_if.if_snd, request);
                   1247:                if (request == 0) {
                   1248:                        /*
                   1249:                         * Tell the lance to send the packet now
                   1250:                         * instead of waiting until the next 1.6 ms
                   1251:                         * poll interval expires.
                   1252:                         */
                   1253:                        *sc->lnregs = LN_CSR0_TDMD | LN_CSR0_INEA;
                   1254:                        splx(s);
                   1255:                        return; /* Nothing on the queue  */
                   1256:                }
                   1257: 
                   1258:                /*
                   1259:                 * Keep request around until transmission complete
                   1260:                 */
                   1261:                sc->tpkt[index] = request;
                   1262:                tlen = copy_to_lance(request, sc->lntbuf[index]);
                   1263: 
                   1264:                /*
                   1265:                 * Give away buffer.  Must copyin/out, set len,
                   1266:                 * and set the OWN flag.  We do not do chaining.
                   1267:                 */
                   1268:                (se_sw->desc_copyin)((vm_offset_t)sc->lntring[index],
                   1269:                                     (vm_offset_t)&r, sizeof(r));
                   1270:                r.buffer_size = -(tlen) | 0xf000;
                   1271:                r.status = (LN_TSTATE_OWN | LN_TSTATE_STP | LN_TSTATE_ENP);
                   1272:                (se_sw->desc_copyout)((vm_offset_t)&r,
                   1273:                                      (vm_offset_t)sc->lntring[index],
                   1274:                                      sizeof(r));
                   1275:                wbflush();
                   1276: 
                   1277:                sc->xmt_count++;
                   1278:        }
                   1279:        /*
                   1280:         * Since we actually have queued new packets, tell
                   1281:         * the chip to rescan the descriptors _now_.
                   1282:         * It is quite unlikely that the ring be filled,
                   1283:         * but if it is .. the more reason to do it!
                   1284:         */
                   1285:        *sc->lnregs = LN_CSR0_TDMD | LN_CSR0_INEA;
                   1286:        splx(s);
                   1287: }
                   1288: 
                   1289: 
                   1290: /*
                   1291:  * Pull a packet off the interface and
                   1292:  * hand it up to the higher levels.
                   1293:  *
                   1294:  * Simulate broadcast packets in software.
                   1295:  */
                   1296: void
                   1297: se_read(
                   1298:        register se_softc_t      sc,
                   1299:        volatile char           *lnrbuf,
                   1300:        int                      len,
                   1301:        io_req_t                 loop_back)
                   1302: {
                   1303:        register struct ifnet *ifp = &sc->is_if;
                   1304:        register ipc_kmsg_t     new_kmsg;
                   1305:        char                    *hdr, *pkt;
                   1306: 
                   1307:        if (len <= sizeof(struct ether_header))
                   1308:                return; /* sanity */
                   1309: 
                   1310:        /*
                   1311:         * Get a new kmsg to put data into.
                   1312:         */
                   1313:        new_kmsg = net_kmsg_get();
                   1314:        if (new_kmsg == IKM_NULL) {
                   1315:            /*
                   1316:             * No room, drop the packet
                   1317:             */
                   1318:            ifp->if_rcvdrops++;
                   1319:            return;
                   1320:        }
                   1321: 
                   1322:        hdr = net_kmsg(new_kmsg)->header;
                   1323:        pkt = net_kmsg(new_kmsg)->packet;
                   1324: 
                   1325: #define OFF0 (sizeof(struct ether_header) - sizeof(struct packet_header))
                   1326: #define OFF1 (OFF0 & ~3)
                   1327:        if (loop_back) {
                   1328:                bcopy(loop_back->io_data, hdr, sizeof(struct ether_header));
                   1329:                bcopy(loop_back->io_data + OFF0,
                   1330:                        pkt, len - OFF0);
                   1331:        } else
                   1332:                copy_from_lance(lnrbuf, len, (struct ether_header*)hdr,
                   1333:                         (struct packet_header*)pkt);
                   1334: 
                   1335:        /*
                   1336:         * Set up the 'fake' header with length.  Type has been left
                   1337:         * in the correct place.
                   1338:         */
                   1339:        len = len - OFF0;
                   1340:        ((struct packet_header *)pkt)->length = len;
                   1341: 
                   1342:        /*
                   1343:         * Hand the packet to the network module.
                   1344:         */
                   1345:        net_packet(ifp, new_kmsg, len, ethernet_priority(new_kmsg));
                   1346: }
                   1347: 
                   1348: 
                   1349: /*
                   1350:  * Get a packet out of Lance memory and into main memory.
                   1351:  */
                   1352: private void
                   1353: copy_from_lance(
                   1354:        register volatile unsigned char *rbuf,
                   1355:        register unsigned int     nbytes,
                   1356:        struct ether_header      *hdr,
                   1357:        struct packet_header     *pkt)
                   1358: {
                   1359:        /*
                   1360:         * Read in ethernet header 
                   1361:         */
                   1362:        (se_sw->data_copyin) ((vm_offset_t)rbuf, (vm_offset_t)hdr, sizeof(struct ether_header));
                   1363: 
                   1364:        nbytes -= sizeof(struct ether_header);
                   1365:        rbuf += (se_sw->mapoffs) (sizeof(struct ether_header));
                   1366: 
                   1367:        pkt->type = (unsigned short) hdr->ether_type;
                   1368: 
                   1369:        (se_sw->data_copyin) ((vm_offset_t)rbuf, (vm_offset_t)(pkt + 1), nbytes);
                   1370: }
                   1371: 
                   1372: 
                   1373: /*
                   1374:  * Move a packet into Lance space
                   1375:  */
                   1376: private int
                   1377: copy_to_lance(
                   1378:        register io_req_t request,
                   1379:        volatile char    *sbuf)
                   1380: {
                   1381:        register unsigned short *dp;
                   1382:        register int    len;
                   1383: 
                   1384:        dp = (unsigned short *) request->io_data;
                   1385:        len = request->io_count;
                   1386: 
                   1387:        if (len > (int)(ETHERMTU + sizeof(struct ether_header))) {
                   1388:                printf("se: truncating HUGE packet\n");
                   1389:                len = ETHERMTU + sizeof(struct ether_header);
                   1390:        }
                   1391: 
                   1392:        (se_sw->data_copyout) ((vm_offset_t)dp, (vm_offset_t)sbuf, len);
                   1393: 
                   1394:        if (len < LN_MINBUF_NOCH)
                   1395:                /*
                   1396:                 * The lance needs at least this much data in a packet. Who
                   1397:                 * cares if I send some garbage that was left in the lance
                   1398:                 * buffer ?  If one can spoof packets then one can spoof
                   1399:                 * packets!
                   1400:                 */
                   1401:                len = LN_MINBUF_NOCH;
                   1402:        return len;
                   1403: }
                   1404: 
                   1405: /*
                   1406:  * Reset a descriptor's flags.
                   1407:  * Optionally give the descriptor to the lance
                   1408:  */
                   1409: private void
                   1410: se_desc_set_status (
                   1411:        register se_desc_t      lndesc,
                   1412:        int                     val)
                   1413: {
                   1414:        struct se_desc          desc;
                   1415: 
                   1416:        (se_sw->desc_copyin) ((vm_offset_t)lndesc, (vm_offset_t)&desc, sizeof(desc));
                   1417:        desc.desc4.bits = 0;
                   1418:        desc.status     = val;
                   1419:        (se_sw->desc_copyout) ((vm_offset_t)&desc, (vm_offset_t)lndesc, sizeof(desc));
                   1420:        wbflush();
                   1421: }
                   1422: 
                   1423: /*
                   1424:  * Set/Get status functions
                   1425:  */
                   1426: int
                   1427: se_get_status(
                   1428:        int              dev,
                   1429:        dev_flavor_t     flavor,
                   1430:        dev_status_t     status,        /* pointer to OUT array */
                   1431:        natural_t       *status_count)  /* out */
                   1432: {
                   1433:        return (net_getstat(&se_softc[dev]->is_if,
                   1434:                            flavor, status, status_count));
                   1435: }
                   1436: 
                   1437: int
                   1438: se_set_status(
                   1439:        int             unit,
                   1440:        dev_flavor_t    flavor,
                   1441:        dev_status_t    status,
                   1442:        natural_t       status_count)
                   1443: {
                   1444:        register se_softc_t     sc;
                   1445: 
                   1446:        sc = se_softc[unit];
                   1447: 
                   1448: 
                   1449:        switch (flavor) {
                   1450: 
                   1451:          case NET_STATUS:
                   1452:                break;
                   1453: 
                   1454:          case NET_ADDRESS: {
                   1455: 
                   1456:                register union ether_cvt {
                   1457:                    unsigned char addr[6];
                   1458:                    int  lwd[2];
                   1459:                } *ec = (union ether_cvt *) status;
                   1460: 
                   1461:                if (status_count < sizeof(*ec) / sizeof(int))
                   1462:                    return (D_INVALID_SIZE);
                   1463: 
                   1464:                ec->lwd[0] = ntohl(ec->lwd[0]);
                   1465:                ec->lwd[1] = ntohl(ec->lwd[1]);
                   1466: 
                   1467:                se_setaddr(ec->addr, unit);
                   1468: 
                   1469:                break;
                   1470:          }
                   1471: 
                   1472:          default:
                   1473:                return (D_INVALID_OPERATION);
                   1474:        }
                   1475: 
                   1476:        return (D_SUCCESS);
                   1477: }
                   1478: 
                   1479: 
                   1480: /*
                   1481:  * Install new filter.
                   1482:  * Nothing special needs to be done here.
                   1483:  */
                   1484: io_return_t
                   1485: se_setinput(
                   1486:        int             dev,
                   1487:        ipc_port_t      receive_port,
                   1488:        int             priority,
                   1489:        filter_t        *filter,
                   1490:        natural_t       filter_count)
                   1491: {
                   1492:        return (net_set_filter(&se_softc[dev]->is_if,
                   1493:                               receive_port, priority,
                   1494:                               filter, filter_count));
                   1495: }
                   1496: 
                   1497: /*
                   1498:  * Allocate and initialize a ring descriptor.
                   1499:  * Allocates a buffer from the lance memory and writes a descriptor
                   1500:  * for that buffer to the host virtual address LNDESC.
                   1501:  */
                   1502: private volatile long
                   1503: *se_desc_alloc (
                   1504:        register se_softc_t     sc,
                   1505:        register se_desc_t      lndesc)
                   1506: {
                   1507:        register vm_offset_t    dp;     /* data pointer */
                   1508:        struct se_desc          desc;
                   1509: 
                   1510:        /*
                   1511:         * Allocate buffer in lance space 
                   1512:         */
                   1513:        dp = se_malloc(sc, LN_BUFFER_SIZE);
                   1514: 
                   1515:        /*
                   1516:         * Build a descriptor pointing to it 
                   1517:         */
                   1518:        desc.addr_low = Addr_lo(Lmem(dp));
                   1519:        desc.addr_hi  = Addr_hi(Lmem(dp));
                   1520:        desc.status   = 0;
                   1521:        desc.buffer_size = -LN_BUFFER_SIZE;
                   1522:        desc.desc4.bits  = 0;
                   1523: 
                   1524:        /*
                   1525:         * Copy the descriptor to lance space 
                   1526:         */
                   1527:        (se_sw->desc_copyout) ((vm_offset_t)&desc, (vm_offset_t)lndesc, sizeof(desc));
                   1528:        wbflush();
                   1529: 
                   1530:        return (volatile long *) Hmem(dp);
                   1531: }
                   1532: 
                   1533: /*
                   1534:  * Allocate a chunk of lance RAM buffer. Since we never
                   1535:  * give lance RAM buffer memory back, we'll just step up the
                   1536:  * byte-count on a per-unit basis.
                   1537:  *
                   1538:  * The return value is an index into the lance memory, which can be
                   1539:  * passed with Hmem() and Lmem() to get the host and chip virtual addresses.
                   1540:  */
                   1541: private vm_offset_t
                   1542: se_malloc(
                   1543:        se_softc_t      sc,
                   1544:        int             size)
                   1545: {
                   1546:        register vm_offset_t    ret;
                   1547: 
                   1548:        /*
                   1549:         * On first call, zero lance memory 
                   1550:         */
                   1551:        if (sc->lnsbrk == 0)
                   1552:                (se_sw->bzero) (Hmem(0), LN_MEMORY_SIZE);
                   1553: 
                   1554:        /*
                   1555:         * Start out on the first double longword boundary
                   1556:         * (this accomodates some machines, with minimal loss)
                   1557:         */
                   1558:        if (sc->lnsbrk & 0xf)
                   1559:                sc->lnsbrk = (sc->lnsbrk + 0x10) & ~0xf;
                   1560: 
                   1561:        ret = sc->lnsbrk;
                   1562:        sc->lnsbrk += size;
                   1563: 
                   1564:        if (sc->lnsbrk > LN_MEMORY_SIZE)
                   1565:                panic("se_malloc");
                   1566: 
                   1567:        return ret;
                   1568: }
                   1569: 
                   1570: #endif     NLN > 0

unix.superglobalmegacorp.com

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