Annotation of driverkit/notes/m68k_ethernet, revision 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.