Annotation of driverkit/notes/m68k_ethernet, revision 1.1.1.1

1.1       root        1: {\rtf0\ansi{\fonttbl\f0\fmodern Ohlfs;\f1\fmodern Courier;}
                      2: \paperw13040
                      3: \paperh10200
                      4: \margl120
                      5: \margr120
                      6: {\colortbl\red0\green0\blue0;}
                      7: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\f0\b0\i0\ul0\fs24                current m68k Etehernet driver notes\
                      8:                \
                      9: 
                     10: \f1\b\fs28 Globals
                     11: \f0\b0\fs24 \
                     12:                \
                     13: struct en_softc en_softc[] - one per interface.\
                     14: \
                     15: 
                     16: \f1\b\fs28 Functions
                     17: \f0\b0\fs24 \
                     18: \
                     19: int enprobe(caddr_t reg, int ctrl) \
                     20: // 
                     21: \f1\b\fs28 called from
                     22: \f0\b0\fs24 : \
                     23: //     via autoconf, in endriver\
                     24: \{\
                     25:        return "real" address 
                     26: \fc0 (w/slot_id_map offset) 
                     27: of en registers;\
                     28: \}\
                     29: \
                     30: int enattach(
                     31: struct bus_device *bd
                     32: ) \
                     33: 
                     34: // 
                     35: \f1\b\fs28 called from
                     36: \f0\b0\fs24 : via autoconf, in endriver\
                     37: 
                     38: \{\
                     39:        get enet address saved by ROM in global etheraddr, save it in \
                     40:                en_softc and write to hardware;\
                     41:        if_attach(
                     42: eninit, NULL, enoutput, engetbuf, encontrol,
                     43:  a slew of args);\
                     44: \}\
                     45: \
                     46: int eninit(netif_t netif)\
                     47: // 
                     48: \f1\b\fs28 called from
                     49: \f0\b0\fs24 :\
                     50: //     en_setaddr\
                     51: /      enattach\
                     52: /      encontrol\
                     53: \{\
                     54:        get *en_softc from netif;\
                     55:        basic "get s/w and h/w state to known condition" stuff;\
                     56:        set new phys address if spec'd in en_softc.is_flags;\
                     57:        queue up 
                     58: NTXBUFS
                     59:  DMA buffers ib en_softc.
                     60: is_tx_free
                     61: ;\
                     62:        queue up 
                     63: NRXBUFS
                     64:  DMA buffers in hardware queue;\
                     65: \}\
                     66: \
                     67: int 
                     68: en_rx_grabbufs(struct en_softc *is)\
                     69: 
                     70: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520 // 
                     71: \f1\b\fs28 called from
                     72: \f0\b0\fs24 :\
                     73: /      timeout() callout from in 
                     74: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 en_rx_dmaintr
                     75: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\fc0 ()
                     76: \
                     77: 
                     78: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 \{\
                     79:        get memory via if_busalloc for all DMA headers in is_rx_free,\
                     80:                enqueue result in hardware queue;\
                     81: \}\
                     82: \
                     83: void en_rx_dmaintr(int unit)\
                     84: 
                     85: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520 // 
                     86: \f1\b\fs28 called from
                     87: \f0\b0\fs24 :\
                     88: /      DMA interrupt handler\
                     89: 
                     90: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 \{\
                     91:        if any DMA errors\
                     92:                log to console (but keep going...!);\
                     93:        get length of packet from DMA engine;\
                     94:        if invalid length \{\
                     95:                log error;\
                     96:                if_errors_set();\
                     97:                re-enqueue this header and buffer on h/w;\
                     98:        \}\
                     99:        nb = if_rbusget(dma buffer, HDR_SIZE + length);\
                    100:        if_handle_input(en_softc->is_if, nb, NULL);\
                    101:        if_busalloc() a new DMA buffer;\
                    102:        if none available\
                    103:                put this header on is_rx_free\
                    104:        else\
                    105:                enqueue this header and buffer on h/w;\
                    106:        record is_last_rx timestamp;\
                    107: \}\
                    108: \
                    109: int enoutput(netif_t netif,\
                    110:         netbuf_t nb,\
                    111:         void *dst)\
                    112: 
                    113: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520 // 
                    114: \f1\b\fs28 called from
                    115: \f0\b0\fs24 :\
                    116: //     higher layer protocol - registered in if_attach() in enattach().\
                    117: 
                    118: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 \{\
                    119:        /*\
                    120:         * Crufty crap:\
                    121:         * \
                    122:         *   struct ifnet *ifp = (struct ifnet *)netif; \
                    123:         *   struct mbuf *m = (struct mbuf *)nb; \
                    124:         *\
                    125:         * Find out from Brad or jks why the "XXX" one these lines and what \
                    126:         * we hope to do about this kind of thing in the future...\
                    127:         */\
                    128:         \
                    129: 
                    130: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520  get *en_softc from netif;\
                    131:        if not running or net down \{\
                    132:                nb_free(nb);\
                    133:                return ENETDOWN;\
                    134:        \}\
                    135: 
                    136: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0      copy dest addr from dst to mtod(m, struct ether_header *);\
                    137:        copy source addr from en_softc to mtod(m, struct ether_header *);\
                    138:        if (IF_QFULL(&ifp->if_snd)) \{\
                    139:                handle queue full error;\
                    140:                return ENOBUFS;\
                    141:        \}\
                    142:        IF_ENQUEUE(&ifp->if_snd, m);\
                    143:        if not active\
                    144:                enstart();\
                    145:        return 0;\
                    146: \}\
                    147: \
                    148: int enstart(dev_t dev)\
                    149: 
                    150: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520 // 
                    151: \f1\b\fs28 called from
                    152: \f0\b0\fs24 :\
                    153: /      
                    154: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 en_tx_dmaintr
                    155: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\fc0 (),
                    156: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0  enoutput
                    157: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\fc0 ()
                    158: \
                    159: 
                    160: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 \{\
                    161:        dequeue an mbuf from our netif;\
                    162:        get a free DMA header from is_tx_free;\
                    163:        if none \{\
                    164:                log error;\
                    165:                nb_free(nb);\
                    166:                return;\
                    167:        \}\
                    168:        if_busalloc(free hdr, netbuf);\
                    169:        calculate DMA start/end registers kludges;\
                    170:        splimp();\
                    171:        start en_jam timeout timer;\
                    172:        dma_enqueue() the header (in h/w if necessary);\
                    173:        set output_active flag;\
                    174:        splx();\
                    175: \}\
                    176: \
                    177: int en_down(int unit)\
                    178: 
                    179: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520 // 
                    180: \f1\b\fs28 called from
                    181: \f0\b0\fs24 :\
                    182: //     boot (to take net down)\
                    183: //     en_jam(), on "I give up, it's broken"\
                    184: 
                    185: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 \{\
                    186:        if_down();\
                    187: \}\
                    188: \
                    189: int en_antijam(struct en_softc *is)\
                    190: 
                    191: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520 // 
                    192: \f1\b\fs28 called from
                    193: \f0\b0\fs24 :\
                    194: //     en_jam, timeout() callout after "I give up"\
                    195: //     untimeout()'d in encontrol(
                    196: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 IFCONTROL_SETFLAGS
                    197: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520 );\
                    198: 
                    199: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 \{\
                    200:        clear jammed flag;\
                    201:        huh???\
                    202: \}\
                    203: \
                    204: int en_jam(struct en_softc *is)\
                    205: 
                    206: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520 // 
                    207: \f1\b\fs28 called from
                    208: \f0\b0\fs24 :\
                    209: //     timeout() callout from enstart();\
                    210: 
                    211: \fc0 //        tx_intr, on "no heartbeat detect"
                    212: \
                    213: 
                    214: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 \{\
                    215:        if thin wire mode \{\
                    216:                if heartbeat on TPE \{\
                    217:                        select TPE;\
                    218:                        return OK;\
                    219:                \}\
                    220:        \}\
                    221:        else \{\
                    222:                if heartbeat\
                    223:                        return OK (Huh???)\
                    224:        \}\
                    225:        log error message;\
                    226:        en_down();\
                    227:        enable en_antijam() timeout;\
                    228:        return error;\
                    229: \}     \
                    230: \
                    231: void en_tx_dmaintr(int unit)\
                    232: 
                    233: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520 // 
                    234: \f1\b\fs28 called from
                    235: \f0\b0\fs24 :\
                    236: //     DMA interrupt handler\
                    237: 
                    238: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 \{\
                    239:        disable en_jam timeout;\
                    240:        while(dhp = dma_dequeue()) \{\
                    241:                if any DMA channel errors \{\
                    242:                        dma_enqueue() this dhp;\
                    243:                        return;\
                    244:                \}\
                    245: 
                    246: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\fc0              if > 16 collision error \{\
                    247:                        if_oerrors_set();\
                    248:                        if jam_count exceeded and not currently jammed \{\
                    249:                                if(en_jam())\
                    250:                                        goto out;\
                    251:                        \}\
                    252:                        dma_enqueue this dhp as a retry;\
                    253:                        return;\
                    254:                \}\
                    255:                if TPE \{\
                    256:                        if en_rx timeout exceeded \{\
                    257:                                /* huh??? this is tx... */\
                    258:                                if(en_jam()) \{\
                    259:                                        dma_enqueue this hdr;\
                    260:                                        return;\
                    261:                                \}\
                    262:                        \}\
                    263:                \}\
                    264: out:\
                    265:                if_busfree(dhp);\
                    266:                enqueue this dhp on is_tx_free;\
                    267: 
                    268: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0      \}\
                    269:        \
                    270:        return;\
                    271: \}\
                    272: \
                    273: int encontrol(netif_t netif,\
                    274:          const char *command,\
                    275:          void *data)\
                    276: 
                    277: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520 // 
                    278: \f1\b\fs28 called from
                    279: \f0\b0\fs24 :\
                    280: //     higher level protocol, registered in if_attaach()\
                    281: 
                    282: \pard\tx1152\tx2304\tx3456\tx4608\tx5760\tx6912\tx8064\tx9216\tx10368\tx11520\fc0 \{\
                    283:        misc crufty stuff;\
                    284: \}\
                    285: \
                    286: \
                    287: 
                    288: \f1\b\fs28 Notes
                    289: \f0\b0\fs24 \
                    290: \
                    291: 1. We should probably NOT use ifnet, ONLY netif_t. Get ptr to local \
                    292:    data (or an id) from the "void *if_private(netif_t netif)" \
                    293:    function in netif.\
                    294: \
                    295: 2. headers, buffers, and stuff\
                    296: \
                    297:    struct mbuf \{\
                    298:        struct  mbuf *m_next;           /* next buffer in chain */\
                    299:        u_long  m_off;                  /* offset of data */\
                    300:        short   m_len;                  /* amount of data in this mbuf */\
                    301:        short   m_type;                 /* mbuf type (0 == free) */\
                    302:        union \{\
                    303:                u_char  mun_dat[MLEN];  /* data storage */\
                    304:                struct \{\
                    305:                        short   mun_cltype;     /* "cluster" type */\
                    306:                        int     (*mun_clfun)();\
                    307:                        int     mun_clarg;\
                    308:                        int     (*mun_clswp)();\
                    309:                \} mun_cl;\
                    310:        \} m_un;\
                    311:        struct  mbuf *m_act;            /* link in higher-level mbuf list */\
                    312:    \};\
                    313: \
                    314:    struct dma_hdr \{\
                    315:        struct dma_hdr *volatile dh_link;/* pts to next dma_hdr in chain */\
                    316:        char *dh_start;                 /* pts to start of buffer for dma */\
                    317:        char *dh_stop;                  /* pts to end of buffer + 1 for dma */\
                    318:        volatile int dh_flags;          /* see below */\
                    319:        volatile int dh_state;          /* csr at time of dma interrupt */\
                    320:        char *volatile dh_next;         /* next at time of dma interrupt */\
                    321:        int dh_drvarg;                  /* for use by driver */\
                    322:    \};\
                    323:    \
                    324:    struct ether_header \{\
                    325:        u_char   ether_dhost[6];\
                    326:        u_char   ether_shost[6];\
                    327:        u_short ether_type;\
                    328:    \};\
                    329: \
                    330:    actual ethernet packet \{\
                    331:        /* \
                    332:         * physically contiguous memory.\
                    333:         * On TX, \
                    334:         */\
                    335:        struct ether_header hdr;\
                    336:        some data;\
                    337:    \}\
                    338:    \
                    339:    struct enbuf \{\
                    340:        union  \{\
                    341:                struct enbuf    *Uenb_next;\
                    342:                char            Uenb_data[BUF_SIZE];\
                    343:        \} Uenbuf;\
                    344:    \};\
                    345:    \
                    346:    enoutput():\
                    347:    \
                    348:        Currently, it's actually passed an mbuf, although this is declared\
                    349:        as a netbuf_t (opaque).\
                    350:    \
                    351:        &ether_header = mbuf->m_off.\
                    352:        \
                    353:    enstart():\
                    354:        This is a total hack. We get an mbuf via IF_DEQUEUE, which should\
                    355:        not be visible to us. Then we cast the mbuf to a netbuf_t. We get\
                    356:        the size of the mbuf via nb_size() (which is legal). Then we cast\
                    357:        a DMA header (which we get from is_tx_free) to a en_dma_buf_t and\
                    358:        pass it to if_busalloc().\
                    359: 
                    360: }

unix.superglobalmegacorp.com

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