midway.c (35210) | midway.c (37939) |
---|---|
1/* $NetBSD: midway.c,v 1.25 1997/03/20 21:34:42 chuck Exp $ */ 2/* (sync'd to midway.c 1.67) */ | 1/* $NetBSD: midway.c,v 1.30 1997/09/29 17:40:38 chuck Exp $ */ 2/* (sync'd to midway.c 1.68) */ |
3 4/* 5 * 6 * Copyright (c) 1996 Charles D. Cranor and Washington University. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions --- 30 unchanged lines hidden (view full) --- 41 * started: spring, 1996 (written from scratch). 42 * 43 * notes from the author: 44 * Extra special thanks go to Werner Almesberger, EPFL LRC. Werner's 45 * ENI driver was especially useful in figuring out how this card works. 46 * I would also like to thank Werner for promptly answering email and being 47 * generally helpful. 48 */ | 3 4/* 5 * 6 * Copyright (c) 1996 Charles D. Cranor and Washington University. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions --- 30 unchanged lines hidden (view full) --- 41 * started: spring, 1996 (written from scratch). 42 * 43 * notes from the author: 44 * Extra special thanks go to Werner Almesberger, EPFL LRC. Werner's 45 * ENI driver was especially useful in figuring out how this card works. 46 * I would also like to thank Werner for promptly answering email and being 47 * generally helpful. 48 */ |
49/* 50 * 1997/12/02 kjc 51 * new features added: 52 * - support vc/vp shaping 53 * - integrate IPv6 support. 54 * - support pvc shadow interface 55 * (initial work on per-pvc-interface for ipv6 was done 56 * by Katsushi Kobayashi <ikob@cc.uec.ac.jp> of the WIDE Project, 57 * extensively modified by kjc.) 58 * code cleanup: 59 * - remove WMAYBE related code. ENI WMAYBE DMA doen't work. 60 * - drop support of FreeBSD-2.1.x and FreeBSD-3.0-SNAP-970124. 61 * - remove updating if_lastchange for every packet. 62 * - BPF related code is moved to midway.c as it should be. 63 * (bpfwrite should work if atm_pseudohdr and LLC/SNAP are 64 * prepended.) 65 * - BPF link type is changed to DLT_ATM_RFC1483. 66 * BPF now understands only LLC/SNAP!! (because bpf can't 67 * handle variable link header length.) 68 * It is recommended to use LLC/SNAP instead of NULL 69 * encapsulation for various reasons. (BPF, IPv6, 70 * interoperability, etc.) 71 * - altq queue implementation is moved from the driver internal 72 * queue to if_snd. 73 * - AFMAP related code cleanup. 74 */ |
|
49 | 75 |
50 | |
51#undef EN_DEBUG 52#undef EN_DEBUG_RANGE /* check ranges on en_read/en_write's? */ 53#define EN_MBUF_OPT /* try and put more stuff in mbuf? */ 54#define EN_DIAG 55#define EN_STAT 56#ifndef EN_DMA 57#define EN_DMA 1 /* use dma? */ 58#endif 59#define EN_NOTXDMA 0 /* hook to disable tx dma only */ 60#define EN_NORXDMA 0 /* hook to disable rx dma only */ | 76#undef EN_DEBUG 77#undef EN_DEBUG_RANGE /* check ranges on en_read/en_write's? */ 78#define EN_MBUF_OPT /* try and put more stuff in mbuf? */ 79#define EN_DIAG 80#define EN_STAT 81#ifndef EN_DMA 82#define EN_DMA 1 /* use dma? */ 83#endif 84#define EN_NOTXDMA 0 /* hook to disable tx dma only */ 85#define EN_NORXDMA 0 /* hook to disable rx dma only */ |
61#define EN_NOWMAYBE 1 /* hook to disable word maybe DMA */ 62 /* XXX: WMAYBE doesn't work, needs debugging */ | |
63#define EN_DDBHOOK 1 /* compile in ddb functions */ | 86#define EN_DDBHOOK 1 /* compile in ddb functions */ |
64#ifdef __FreeBSD__ 65/* somehow, misaligned DMA doesn't work on FreeBSD with ENI card. 66 * not sure if this is specific to FreeBSD. 67 * anyway, always fix unaligned or word fragmented mbufs. --kjc */ 68#define EN_FIXMBUF | 87#if defined(MIDWAY_ADPONLY) 88#define EN_ENIDMAFIX 0 /* no ENI cards to worry about */ 89#else 90#define EN_ENIDMAFIX 1 /* avoid byte DMA on the ENI card (see below) */ |
69#endif 70 | 91#endif 92 |
93/* 94 * note on EN_ENIDMAFIX: the byte aligner on the ENI version of the card 95 * appears to be broken. it works just fine if there is no load... however 96 * when the card is loaded the data get corrupted. to see this, one only 97 * has to use "telnet" over ATM. do the following command in "telnet": 98 * cat /usr/share/misc/termcap 99 * "telnet" seems to generate lots of 1023 byte mbufs (which make great 100 * use of the byte aligner). watch "netstat -s" for checksum errors. 101 * 102 * I further tested this by adding a function that compared the transmit 103 * data on the card's SRAM with the data in the mbuf chain _after_ the 104 * "transmit DMA complete" interrupt. using the "telnet" test I got data 105 * mismatches where the byte-aligned data should have been. using ddb 106 * and en_dumpmem() I verified that the DTQs fed into the card were 107 * absolutely correct. thus, we are forced to concluded that the ENI 108 * hardware is buggy. note that the Adaptec version of the card works 109 * just fine with byte DMA. 110 * 111 * bottom line: we set EN_ENIDMAFIX to 1 to avoid byte DMAs on the ENI 112 * card. 113 */ 114 |
|
71#if defined(DIAGNOSTIC) && !defined(EN_DIAG) 72#define EN_DIAG /* link in with master DIAG option */ 73#endif 74#ifdef EN_STAT 75#define EN_COUNT(X) (X)++ 76#else 77#define EN_COUNT(X) /* nothing */ 78#endif --- 13 unchanged lines hidden (view full) --- 92#include "opt_inet.h" 93#include "opt_natm.h" 94#endif 95 96#if NEN > 0 || !defined(__FreeBSD__) 97 98#include <sys/param.h> 99#include <sys/systm.h> | 115#if defined(DIAGNOSTIC) && !defined(EN_DIAG) 116#define EN_DIAG /* link in with master DIAG option */ 117#endif 118#ifdef EN_STAT 119#define EN_COUNT(X) (X)++ 120#else 121#define EN_COUNT(X) /* nothing */ 122#endif --- 13 unchanged lines hidden (view full) --- 136#include "opt_inet.h" 137#include "opt_natm.h" 138#endif 139 140#if NEN > 0 || !defined(__FreeBSD__) 141 142#include <sys/param.h> 143#include <sys/systm.h> |
144#include <sys/queue.h> |
|
100#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) 101#include <sys/device.h> 102#endif 103#include <sys/sockio.h> 104#include <sys/mbuf.h> 105#include <sys/socket.h> | 145#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) 146#include <sys/device.h> 147#endif 148#include <sys/sockio.h> 149#include <sys/mbuf.h> 150#include <sys/socket.h> |
151#include <sys/proc.h> |
|
106 107#include <net/if.h> 108#include <net/if_atm.h> 109 110#include <vm/vm.h> 111 | 152 153#include <net/if.h> 154#include <net/if_atm.h> 155 156#include <vm/vm.h> 157 |
112#ifdef INET | 158#if defined(INET) || defined(INET6) 159#include <netinet/in.h> |
113#include <netinet/if_atm.h> 114#endif 115 116#ifdef NATM | 160#include <netinet/if_atm.h> 161#endif 162 163#ifdef NATM |
117#include <netinet/in.h> | |
118#include <netnatm/natm.h> 119#endif 120 | 164#include <netnatm/natm.h> 165#endif 166 |
121 | |
122#if !defined(sparc) && !defined(__FreeBSD__) 123#include <machine/bus.h> 124#endif 125 126#if defined(__NetBSD__) || defined(__OpenBSD__) 127#include <dev/ic/midwayreg.h> 128#include <dev/ic/midwayvar.h> 129#if defined(__alpha__) 130/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */ 131#undef vtophys 132#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va)) 133#endif 134#elif defined(__FreeBSD__) 135#include <machine/clock.h> /* for DELAY */ 136#include <dev/en/midwayreg.h> 137#include <dev/en/midwayvar.h> 138#include <vm/pmap.h> /* for vtophys proto */ 139 | 167#if !defined(sparc) && !defined(__FreeBSD__) 168#include <machine/bus.h> 169#endif 170 171#if defined(__NetBSD__) || defined(__OpenBSD__) 172#include <dev/ic/midwayreg.h> 173#include <dev/ic/midwayvar.h> 174#if defined(__alpha__) 175/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */ 176#undef vtophys 177#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va)) 178#endif 179#elif defined(__FreeBSD__) 180#include <machine/clock.h> /* for DELAY */ 181#include <dev/en/midwayreg.h> 182#include <dev/en/midwayvar.h> 183#include <vm/pmap.h> /* for vtophys proto */ 184 |
140/* 141 * 2.1.x does not have if_softc. detect this by seeing if IFF_NOTRAILERS 142 * is defined, as per kjc. 143 */ 144#ifdef IFF_NOTRAILERS 145#define MISSING_IF_SOFTC 146#else | 185#ifndef IFF_NOTRAILERS |
147#define IFF_NOTRAILERS 0 148#endif 149 150#endif /* __FreeBSD__ */ 151 | 186#define IFF_NOTRAILERS 0 187#endif 188 189#endif /* __FreeBSD__ */ 190 |
191#include "bpfilter.h" 192#if NBPFILTER > 0 193#include <net/bpf.h> 194#ifdef __FreeBSD__ 195#define BPFATTACH(ifp, dlt, hlen) bpfattach((ifp), (dlt), (hlen)) 196#define BPF_MTAP(ifp, m) bpf_mtap((ifp), (m)) 197#else 198#define BPFATTACH(ifp, dlt, hlen) bpfattach(&(ifp)->if_bpf, (ifp), (dlt), (hlen)) 199#define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m)) 200#endif 201#endif /* NBPFILTER > 0 */ 202 |
|
152/* 153 * params 154 */ 155 156#ifndef EN_TXHIWAT 157#define EN_TXHIWAT (64*1024) /* max 64 KB waiting to be DMAd out */ 158#endif 159 --- 41 unchanged lines hidden (view full) --- 201 u_int32_t atm_vci; /* vci */ 202 u_int8_t atm_flags; /* flags */ 203}; 204 205 206/* 207 * dma table (index by # of words) 208 * | 203/* 204 * params 205 */ 206 207#ifndef EN_TXHIWAT 208#define EN_TXHIWAT (64*1024) /* max 64 KB waiting to be DMAd out */ 209#endif 210 --- 41 unchanged lines hidden (view full) --- 252 u_int32_t atm_vci; /* vci */ 253 u_int8_t atm_flags; /* flags */ 254}; 255 256 257/* 258 * dma table (index by # of words) 259 * |
209 * plan A: use WMAYBE | 260 * plan A: use WMAYBE (obsolete) |
210 * plan B: avoid WMAYBE 211 */ 212 213struct en_dmatab { 214 u_int8_t bcode; /* code */ 215 u_int8_t divshift; /* byte divisor */ 216}; 217 | 261 * plan B: avoid WMAYBE 262 */ 263 264struct en_dmatab { 265 u_int8_t bcode; /* code */ 266 u_int8_t divshift; /* byte divisor */ 267}; 268 |
218static struct en_dmatab en_dma_planA[] = { 219 { 0, 0 }, /* 0 */ { MIDDMA_WORD, 2 }, /* 1 */ 220 { MIDDMA_2WORD, 3}, /* 2 */ { MIDDMA_4WMAYBE, 2}, /* 3 */ 221 { MIDDMA_4WORD, 4}, /* 4 */ { MIDDMA_8WMAYBE, 2}, /* 5 */ 222 { MIDDMA_8WMAYBE, 2}, /* 6 */ { MIDDMA_8WMAYBE, 2}, /* 7 */ 223 { MIDDMA_8WORD, 5}, /* 8 */ { MIDDMA_16WMAYBE, 2}, /* 9 */ 224 { MIDDMA_16WMAYBE,2}, /* 10 */ { MIDDMA_16WMAYBE, 2}, /* 11 */ 225 { MIDDMA_16WMAYBE,2}, /* 12 */ { MIDDMA_16WMAYBE, 2}, /* 13 */ 226 { MIDDMA_16WMAYBE,2}, /* 14 */ { MIDDMA_16WMAYBE, 2}, /* 15 */ 227 { MIDDMA_16WORD, 6}, /* 16 */ 228}; 229 | |
230static struct en_dmatab en_dma_planB[] = { 231 { 0, 0 }, /* 0 */ { MIDDMA_WORD, 2}, /* 1 */ 232 { MIDDMA_2WORD, 3}, /* 2 */ { MIDDMA_WORD, 2}, /* 3 */ 233 { MIDDMA_4WORD, 4}, /* 4 */ { MIDDMA_WORD, 2}, /* 5 */ 234 { MIDDMA_2WORD, 3}, /* 6 */ { MIDDMA_WORD, 2}, /* 7 */ 235 { MIDDMA_8WORD, 5}, /* 8 */ { MIDDMA_WORD, 2}, /* 9 */ 236 { MIDDMA_2WORD, 3}, /* 10 */ { MIDDMA_WORD, 2}, /* 11 */ 237 { MIDDMA_4WORD, 4}, /* 12 */ { MIDDMA_WORD, 2}, /* 13 */ 238 { MIDDMA_2WORD, 3}, /* 14 */ { MIDDMA_WORD, 2}, /* 15 */ 239 { MIDDMA_16WORD, 6}, /* 16 */ 240}; 241 | 269static struct en_dmatab en_dma_planB[] = { 270 { 0, 0 }, /* 0 */ { MIDDMA_WORD, 2}, /* 1 */ 271 { MIDDMA_2WORD, 3}, /* 2 */ { MIDDMA_WORD, 2}, /* 3 */ 272 { MIDDMA_4WORD, 4}, /* 4 */ { MIDDMA_WORD, 2}, /* 5 */ 273 { MIDDMA_2WORD, 3}, /* 6 */ { MIDDMA_WORD, 2}, /* 7 */ 274 { MIDDMA_8WORD, 5}, /* 8 */ { MIDDMA_WORD, 2}, /* 9 */ 275 { MIDDMA_2WORD, 3}, /* 10 */ { MIDDMA_WORD, 2}, /* 11 */ 276 { MIDDMA_4WORD, 4}, /* 12 */ { MIDDMA_WORD, 2}, /* 13 */ 277 { MIDDMA_2WORD, 3}, /* 14 */ { MIDDMA_WORD, 2}, /* 15 */ 278 { MIDDMA_16WORD, 6}, /* 16 */ 279}; 280 |
242static struct en_dmatab *en_dmaplan = en_dma_planA; 243 | 281static struct en_dmatab *en_dmaplan = en_dma_planB; 282 |
244/* 245 * prototypes 246 */ 247 | 283/* 284 * prototypes 285 */ 286 |
248STATIC int en_b2sz __P((int)); | 287STATIC INLINE int en_b2sz __P((int)) __attribute__ ((unused)); |
249#ifdef EN_DDBHOOK | 288#ifdef EN_DDBHOOK |
250int en_dump __P((int,int)); 251int en_dumpmem __P((int,int,int)); | 289 int en_dump __P((int,int)); 290 int en_dumpmem __P((int,int,int)); |
252#endif | 291#endif |
253STATIC void en_dmaprobe __P((struct en_softc *)); 254STATIC int en_dmaprobe_doit __P((struct en_softc *, u_int8_t *, 255 u_int8_t *, int)); 256STATIC int en_dqneed __P((struct en_softc *, caddr_t, u_int, u_int)); 257STATIC void en_init __P((struct en_softc *)); 258STATIC int en_ioctl __P((struct ifnet *, EN_IOCTL_CMDT, caddr_t)); 259STATIC int en_k2sz __P((int)); 260STATIC void en_loadvc __P((struct en_softc *, int)); 261STATIC int en_mfix __P((struct en_softc *, struct mbuf **, struct mbuf *)); 262STATIC struct mbuf *en_mget __P((struct en_softc *, u_int, u_int *)); 263STATIC u_int32_t en_read __P((struct en_softc *, u_int32_t)); 264STATIC int en_rxctl __P((struct en_softc *, struct atm_pseudoioctl *, int)); 265STATIC void en_txdma __P((struct en_softc *, int)); 266STATIC void en_txlaunch __P((struct en_softc *, int, struct en_launch *)); 267STATIC void en_service __P((struct en_softc *)); 268STATIC void en_start __P((struct ifnet *)); 269STATIC int en_sz2b __P((int)); 270STATIC void en_write __P((struct en_softc *, u_int32_t, u_int32_t)); | 292STATIC void en_dmaprobe __P((struct en_softc *)); 293STATIC int en_dmaprobe_doit __P((struct en_softc *, u_int8_t *, 294 u_int8_t *, int)); 295STATIC INLINE int en_dqneed __P((struct en_softc *, caddr_t, u_int, 296 u_int)) __attribute__ ((unused)); 297STATIC void en_init __P((struct en_softc *)); 298STATIC int en_ioctl __P((struct ifnet *, EN_IOCTL_CMDT, caddr_t)); 299STATIC INLINE int en_k2sz __P((int)) __attribute__ ((unused)); 300STATIC void en_loadvc __P((struct en_softc *, int)); 301STATIC int en_mfix __P((struct en_softc *, struct mbuf **, 302 struct mbuf *)); 303STATIC INLINE struct mbuf *en_mget __P((struct en_softc *, u_int, 304 u_int *)) __attribute__ ((unused)); 305STATIC INLINE u_int32_t en_read __P((struct en_softc *, 306 u_int32_t)) __attribute__ ((unused)); 307STATIC int en_rxctl __P((struct en_softc *, struct atm_pseudoioctl *, 308 int)); 309STATIC void en_txdma __P((struct en_softc *, int)); 310STATIC void en_txlaunch __P((struct en_softc *, int, 311 struct en_launch *)); 312STATIC void en_service __P((struct en_softc *)); 313STATIC void en_start __P((struct ifnet *)); 314STATIC INLINE int en_sz2b __P((int)) __attribute__ ((unused)); 315STATIC INLINE void en_write __P((struct en_softc *, u_int32_t, 316 u_int32_t)) __attribute__ ((unused)); |
271 | 317 |
318#ifdef ATM_PVCEXT 319static int en_txctl __P((struct en_softc *, int, int, int)); 320static int en_pvctx __P((struct en_softc *, struct pvctxreq *)); 321static int en_pvctxget __P((struct en_softc *, struct pvctxreq *)); 322static int en_pcr2txspeed __P((int)); 323static int en_txspeed2pcr __P((int)); 324#endif 325 |
|
272/* 273 * macros/inline 274 */ 275 276/* 277 * raw read/write macros 278 */ 279 --- 311 unchanged lines hidden (view full) --- 591 if (top) { 592 MGET(m, M_DONTWAIT, MT_DATA); 593 if (!m) { 594 m_freem(top); 595 return(NULL); /* out of mbufs */ 596 } 597 m->m_len = MLEN; 598 } | 326/* 327 * macros/inline 328 */ 329 330/* 331 * raw read/write macros 332 */ 333 --- 311 unchanged lines hidden (view full) --- 645 if (top) { 646 MGET(m, M_DONTWAIT, MT_DATA); 647 if (!m) { 648 m_freem(top); 649 return(NULL); /* out of mbufs */ 650 } 651 m->m_len = MLEN; 652 } |
599 if (top && totlen >= MINCLSIZE) { | 653 if (totlen >= MINCLSIZE) { |
600 MCLGET(m, M_DONTWAIT); | 654 MCLGET(m, M_DONTWAIT); |
601 if (m->m_flags & M_EXT) 602 m->m_len = MCLBYTES; | 655 if ((m->m_flags & M_EXT) == 0) { 656 m_free(m); 657 m_freem(top); 658 return(NULL); /* out of mbuf clusters */ 659 } 660 m->m_len = MCLBYTES; |
603 } 604 m->m_len = min(totlen, m->m_len); 605 totlen -= m->m_len; 606 *mp = m; 607 mp = &m->m_next; 608 609 *drqneed += en_dqneed(sc, m->m_data, m->m_len, 0); 610 --- 71 unchanged lines hidden (view full) --- 682 else 683 printf("%s: FAILED DMA TEST: burst=%d, alburst=%d\n", 684 sc->sc_dev.dv_xname, sc->bestburstlen, sc->alburst); 685 } else { 686 printf("%s: maximum DMA burst length = %d bytes%s\n", sc->sc_dev.dv_xname, 687 sc->bestburstlen, (sc->alburst) ? " (must align)" : ""); 688 } 689 | 661 } 662 m->m_len = min(totlen, m->m_len); 663 totlen -= m->m_len; 664 *mp = m; 665 mp = &m->m_next; 666 667 *drqneed += en_dqneed(sc, m->m_data, m->m_len, 0); 668 --- 71 unchanged lines hidden (view full) --- 740 else 741 printf("%s: FAILED DMA TEST: burst=%d, alburst=%d\n", 742 sc->sc_dev.dv_xname, sc->bestburstlen, sc->alburst); 743 } else { 744 printf("%s: maximum DMA burst length = %d bytes%s\n", sc->sc_dev.dv_xname, 745 sc->bestburstlen, (sc->alburst) ? " (must align)" : ""); 746 } 747 |
690#if 0 /* WMAYBE doesn't work, don't complain about it */ 691 /* check if en_dmaprobe disabled wmaybe */ 692 if (en_dmaplan == en_dma_planB) 693 printf("%s: note: WMAYBE DMA has been disabled\n", sc->sc_dev.dv_xname); 694#endif 695 | |
696 /* 697 * link into network subsystem and prepare card 698 */ 699 700#if defined(__NetBSD__) || defined(__OpenBSD__) 701 bcopy(sc->sc_dev.dv_xname, sc->enif.if_xname, IFNAMSIZ); 702#endif | 748 /* 749 * link into network subsystem and prepare card 750 */ 751 752#if defined(__NetBSD__) || defined(__OpenBSD__) 753 bcopy(sc->sc_dev.dv_xname, sc->enif.if_xname, IFNAMSIZ); 754#endif |
703#if !defined(MISSING_IF_SOFTC) | |
704 sc->enif.if_softc = sc; | 755 sc->enif.if_softc = sc; |
705#endif | |
706 ifp->if_flags = IFF_SIMPLEX|IFF_NOTRAILERS; 707 ifp->if_ioctl = en_ioctl; 708 ifp->if_output = atm_output; 709 ifp->if_start = en_start; 710 711 /* 712 * init softc 713 */ --- 30 unchanged lines hidden (view full) --- 744 sav = ptr; 745 ptr = roundup(ptr, EN_RXSZ * 1024); /* align */ 746 sz = sz - (ptr - sav); 747 sc->en_nrx = sz / (EN_RXSZ * 1024); 748 if (sc->en_nrx <= 0) { 749 printf("%s: EN_NTX/EN_TXSZ/EN_RXSZ too big\n", sc->sc_dev.dv_xname); 750 return; 751 } | 756 ifp->if_flags = IFF_SIMPLEX|IFF_NOTRAILERS; 757 ifp->if_ioctl = en_ioctl; 758 ifp->if_output = atm_output; 759 ifp->if_start = en_start; 760 761 /* 762 * init softc 763 */ --- 30 unchanged lines hidden (view full) --- 794 sav = ptr; 795 ptr = roundup(ptr, EN_RXSZ * 1024); /* align */ 796 sz = sz - (ptr - sav); 797 sc->en_nrx = sz / (EN_RXSZ * 1024); 798 if (sc->en_nrx <= 0) { 799 printf("%s: EN_NTX/EN_TXSZ/EN_RXSZ too big\n", sc->sc_dev.dv_xname); 800 return; 801 } |
752#if 1 753 /* leave one entry in the ringbuf unused to avoid wraparound */ | 802 803 /* 804 * ensure that there is always one VC slot on the service list free 805 * so that we can tell the difference between a full and empty list. 806 */ |
754 if (sc->en_nrx >= MID_N_VC) | 807 if (sc->en_nrx >= MID_N_VC) |
755 sc->en_nrx = MID_N_VC - 1; 756#endif | 808 sc->en_nrx = MID_N_VC - 1; 809 |
757 for (lcv = 0 ; lcv < sc->en_nrx ; lcv++) { 758 sc->rxslot[lcv].rxhand = NULL; 759 sc->rxslot[lcv].oth_flags = ENOTHER_FREE; 760 bzero(&sc->rxslot[lcv].indma, sizeof(sc->rxslot[lcv].indma)); 761 bzero(&sc->rxslot[lcv].q, sizeof(sc->rxslot[lcv].q)); 762 midvloc = sc->rxslot[lcv].start = ptr; 763 ptr += (EN_RXSZ * 1024); 764 sz -= (EN_RXSZ * 1024); --- 18 unchanged lines hidden (view full) --- 783 sc->rxdrqout = sc->ttrash = sc->rxmbufout = sc->mfixfail = 0; 784 sc->headbyte = sc->tailbyte = sc->tailflush = 0; 785#endif 786 sc->need_drqs = sc->need_dtqs = 0; 787 788 printf("%s: %d %dKB receive buffers, %d %dKB transmit buffers allocated\n", 789 sc->sc_dev.dv_xname, sc->en_nrx, EN_RXSZ, EN_NTX, EN_TXSZ); 790 | 810 for (lcv = 0 ; lcv < sc->en_nrx ; lcv++) { 811 sc->rxslot[lcv].rxhand = NULL; 812 sc->rxslot[lcv].oth_flags = ENOTHER_FREE; 813 bzero(&sc->rxslot[lcv].indma, sizeof(sc->rxslot[lcv].indma)); 814 bzero(&sc->rxslot[lcv].q, sizeof(sc->rxslot[lcv].q)); 815 midvloc = sc->rxslot[lcv].start = ptr; 816 ptr += (EN_RXSZ * 1024); 817 sz -= (EN_RXSZ * 1024); --- 18 unchanged lines hidden (view full) --- 836 sc->rxdrqout = sc->ttrash = sc->rxmbufout = sc->mfixfail = 0; 837 sc->headbyte = sc->tailbyte = sc->tailflush = 0; 838#endif 839 sc->need_drqs = sc->need_dtqs = 0; 840 841 printf("%s: %d %dKB receive buffers, %d %dKB transmit buffers allocated\n", 842 sc->sc_dev.dv_xname, sc->en_nrx, EN_RXSZ, EN_NTX, EN_TXSZ); 843 |
844 printf("%s: End Station Identifier (mac address) %6D\n", 845 sc->sc_dev.dv_xname, sc->macaddr, ":"); 846 |
|
791 /* 792 * final commit 793 */ 794 795 if_attach(ifp); 796 atm_ifattach(ifp); 797 | 847 /* 848 * final commit 849 */ 850 851 if_attach(ifp); 852 atm_ifattach(ifp); 853 |
854#if NBPFILTER > 0 855 BPFATTACH(ifp, DLT_ATM_RFC1483, sizeof(struct atmllc)); 856#endif |
|
798} 799 800 801/* 802 * en_dmaprobe: helper function for en_attach. 803 * 804 * see how the card handles DMA by running a few DMA tests. we need 805 * to figure out the largest number of bytes we can DMA in one burst 806 * ("bestburstlen"), and if the starting address for a burst needs to 807 * be aligned on any sort of boundary or not ("alburst"). 808 * 809 * typical findings: 810 * sparc1: bestburstlen=4, alburst=0 (ick, broken DMA!) 811 * sparc2: bestburstlen=64, alburst=1 812 * p166: bestburstlen=64, alburst=0 813 */ 814 | 857} 858 859 860/* 861 * en_dmaprobe: helper function for en_attach. 862 * 863 * see how the card handles DMA by running a few DMA tests. we need 864 * to figure out the largest number of bytes we can DMA in one burst 865 * ("bestburstlen"), and if the starting address for a burst needs to 866 * be aligned on any sort of boundary or not ("alburst"). 867 * 868 * typical findings: 869 * sparc1: bestburstlen=4, alburst=0 (ick, broken DMA!) 870 * sparc2: bestburstlen=64, alburst=1 871 * p166: bestburstlen=64, alburst=0 872 */ 873 |
874#if 1 /* __FreeBSD__ */ 875#define NBURSTS 3 /* number of bursts to use for dmaprobe */ 876#define BOUNDARY 1024 /* test misaligned dma crossing the bounday. 877 should be n * 64. at least 64*(NBURSTS+1). 878 dell P6 with EDO DRAM has 1K bounday problem */ 879#endif 880 |
|
815STATIC void en_dmaprobe(sc) 816 817struct en_softc *sc; 818 819{ | 881STATIC void en_dmaprobe(sc) 882 883struct en_softc *sc; 884 885{ |
886#ifdef NBURSTS 887 /* be careful. kernel stack is only 8K */ 888 u_int8_t buffer[BOUNDARY * 2 + 64 * (NBURSTS + 1)]; 889#else |
|
820 u_int32_t srcbuf[64], dstbuf[64]; | 890 u_int32_t srcbuf[64], dstbuf[64]; |
891#endif |
|
821 u_int8_t *sp, *dp; | 892 u_int8_t *sp, *dp; |
822 int bestalgn, bestnotalgn, lcv, try, fail; | 893 int bestalgn, bestnotalgn, lcv, try; |
823 824 sc->alburst = 0; 825 | 894 895 sc->alburst = 0; 896 |
897#ifdef NBURSTS 898 /* setup src and dst buf at the end of the boundary */ 899 sp = (u_int8_t *)roundup((unsigned long)buffer, 64); 900 while (((unsigned long)sp & (BOUNDARY - 1)) != (BOUNDARY - 64)) 901 sp += 64; 902 dp = sp + BOUNDARY; 903 904 /* 905 * we can't dma across page boundary so that, if buf is at a page 906 * boundary, move it to the next page. but still either src or dst 907 * will be at the boundary, which should be ok. 908 */ 909 if ((((unsigned long)sp + 64) & PAGE_MASK) == 0) 910 sp += 64; 911 if ((((unsigned long)dp + 64) & PAGE_MASK) == 0) 912 dp += 64; 913#else /* !NBURSTS */ |
|
826 sp = (u_int8_t *) srcbuf; 827 while ((((unsigned long) sp) % MIDDMA_MAXBURST) != 0) 828 sp += 4; 829 dp = (u_int8_t *) dstbuf; 830 while ((((unsigned long) dp) % MIDDMA_MAXBURST) != 0) 831 dp += 4; | 914 sp = (u_int8_t *) srcbuf; 915 while ((((unsigned long) sp) % MIDDMA_MAXBURST) != 0) 916 sp += 4; 917 dp = (u_int8_t *) dstbuf; 918 while ((((unsigned long) dp) % MIDDMA_MAXBURST) != 0) 919 dp += 4; |
920#endif /* !NBURSTS */ |
|
832 833 bestalgn = bestnotalgn = en_dmaprobe_doit(sc, sp, dp, 0); 834 835 for (lcv = 4 ; lcv < MIDDMA_MAXBURST ; lcv += 4) { 836 try = en_dmaprobe_doit(sc, sp+lcv, dp+lcv, 0); | 921 922 bestalgn = bestnotalgn = en_dmaprobe_doit(sc, sp, dp, 0); 923 924 for (lcv = 4 ; lcv < MIDDMA_MAXBURST ; lcv += 4) { 925 try = en_dmaprobe_doit(sc, sp+lcv, dp+lcv, 0); |
926#ifdef NBURSTS 927 if (try < bestnotalgn) { 928 bestnotalgn = try; 929 break; 930 } 931#else |
|
837 if (try < bestnotalgn) 838 bestnotalgn = try; | 932 if (try < bestnotalgn) 933 bestnotalgn = try; |
934#endif |
|
839 } 840 841 if (bestalgn != bestnotalgn) /* need bursts aligned */ 842 sc->alburst = 1; 843 844 sc->bestburstlen = bestalgn; 845 sc->bestburstshift = en_log2(bestalgn); 846 sc->bestburstmask = sc->bestburstlen - 1; /* must be power of 2 */ 847 sc->bestburstcode = en_sz2b(bestalgn); 848 | 935 } 936 937 if (bestalgn != bestnotalgn) /* need bursts aligned */ 938 sc->alburst = 1; 939 940 sc->bestburstlen = bestalgn; 941 sc->bestburstshift = en_log2(bestalgn); 942 sc->bestburstmask = sc->bestburstlen - 1; /* must be power of 2 */ 943 sc->bestburstcode = en_sz2b(bestalgn); 944 |
849 if (sc->bestburstlen <= 2*sizeof(u_int32_t)) 850 return; /* won't be using WMAYBE */ 851 | 945#if 1 /* __FreeBSD__ */ |
852 /* | 946 /* |
853 * adaptec does not have (or need) wmaybe. do not bother testing 854 * for it. | 947 * correct pci chipsets should be able to handle misaligned-64-byte DMA. 948 * but there are too many broken chipsets around. we try to work around 949 * by finding the best workable dma size, but still some broken machines 950 * exhibit the problem later. so warn it here. |
855 */ | 951 */ |
856 if (sc->is_adaptec) { 857 /* XXX, actually don't need a DMA plan: adaptec is smarter than that */ 858 en_dmaplan = en_dma_planB; 859 return; | 952 if (bestalgn != 64 || sc->alburst != 0) { 953 printf("%s: WARNING: DMA test detects a broken PCI chipset!\n", 954 sc->sc_dev.dv_xname); 955 printf(" trying to work around the problem... but if this doesn't\n"); 956 printf(" work for you, you'd better switch to a newer motherboard.\n"); |
860 } | 957 } |
861 862 /* 863 * test that WMAYBE dma works like we think it should 864 * (i.e. no alignment restrictions on host address other than alburst) 865 */ 866 867 try = sc->bestburstlen - 4; 868 fail = 0; 869 fail += en_dmaprobe_doit(sc, sp, dp, try); 870 for (lcv = 4 ; lcv < sc->bestburstlen ; lcv += 4) { 871 fail += en_dmaprobe_doit(sc, sp+lcv, dp+lcv, try); 872 if (sc->alburst) 873 try -= 4; 874 } 875 if (EN_NOWMAYBE || fail) { 876 if (fail) 877 printf("%s: WARNING: WMAYBE DMA test failed %d time(s)\n", 878 sc->sc_dev.dv_xname, fail); 879 en_dmaplan = en_dma_planB; /* fall back to plan B */ 880 } 881 | 958#endif /* 1 */ 959 return; |
882} 883 884 885/* 886 * en_dmaprobe_doit: do actual testing 887 */ 888 889int --- 17 unchanged lines hidden (view full) --- 907 908 midvloc = ((MID_BUFOFF - MID_RAMOFF) / sizeof(u_int32_t)) >> MIDV_LOCTOPSHFT; 909 EN_WRITE(sc, MIDX_PLACE(0), MIDX_MKPLACE(en_k2sz(1), midvloc)); 910 EN_WRITE(sc, MID_VC(0), (midvloc << MIDV_LOCSHIFT) 911 | (en_k2sz(1) << MIDV_SZSHIFT) | MIDV_TRASH); 912 EN_WRITE(sc, MID_DST_RP(0), 0); 913 EN_WRITE(sc, MID_WP_ST_CNT(0), 0); 914 | 960} 961 962 963/* 964 * en_dmaprobe_doit: do actual testing 965 */ 966 967int --- 17 unchanged lines hidden (view full) --- 985 986 midvloc = ((MID_BUFOFF - MID_RAMOFF) / sizeof(u_int32_t)) >> MIDV_LOCTOPSHFT; 987 EN_WRITE(sc, MIDX_PLACE(0), MIDX_MKPLACE(en_k2sz(1), midvloc)); 988 EN_WRITE(sc, MID_VC(0), (midvloc << MIDV_LOCSHIFT) 989 | (en_k2sz(1) << MIDV_SZSHIFT) | MIDV_TRASH); 990 EN_WRITE(sc, MID_DST_RP(0), 0); 991 EN_WRITE(sc, MID_WP_ST_CNT(0), 0); 992 |
993#ifdef NBURSTS 994 for (lcv = 0 ; lcv < 64*NBURSTS; lcv++) /* set up sample data */ 995#else |
|
915 for (lcv = 0 ; lcv < 68 ; lcv++) /* set up sample data */ | 996 for (lcv = 0 ; lcv < 68 ; lcv++) /* set up sample data */ |
997#endif |
|
916 sp[lcv] = lcv+1; 917 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* enable DMA (only) */ 918 919 sc->drq_chip = MID_DRQ_REG2A(EN_READ(sc, MID_DMA_RDRX)); 920 sc->dtq_chip = MID_DTQ_REG2A(EN_READ(sc, MID_DMA_RDTX)); 921 922 /* 923 * try it now . . . DMA it out, then DMA it back in and compare --- 5 unchanged lines hidden (view full) --- 929 * note: we've got two different tests rolled up in the same loop 930 * if (wmtry) 931 * then we are doing a wmaybe test and wmtry is a byte count 932 * else we are doing a burst test 933 */ 934 935 for (lcv = 8 ; lcv <= MIDDMA_MAXBURST ; lcv = lcv * 2) { 936 | 998 sp[lcv] = lcv+1; 999 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* enable DMA (only) */ 1000 1001 sc->drq_chip = MID_DRQ_REG2A(EN_READ(sc, MID_DMA_RDRX)); 1002 sc->dtq_chip = MID_DTQ_REG2A(EN_READ(sc, MID_DMA_RDTX)); 1003 1004 /* 1005 * try it now . . . DMA it out, then DMA it back in and compare --- 5 unchanged lines hidden (view full) --- 1011 * note: we've got two different tests rolled up in the same loop 1012 * if (wmtry) 1013 * then we are doing a wmaybe test and wmtry is a byte count 1014 * else we are doing a burst test 1015 */ 1016 1017 for (lcv = 8 ; lcv <= MIDDMA_MAXBURST ; lcv = lcv * 2) { 1018 |
1019#ifdef EN_DEBUG 1020 printf("DMA test lcv=%d, sp=0x%x, dp=0x%x, wmtry=%d\n", 1021 lcv, sp, dp, wmtry); 1022#endif 1023 |
|
937 /* zero SRAM and dest buffer */ 938 for (cnt = 0 ; cnt < 1024; cnt += 4) 939 EN_WRITE(sc, MID_BUFOFF+cnt, 0); /* zero memory */ | 1024 /* zero SRAM and dest buffer */ 1025 for (cnt = 0 ; cnt < 1024; cnt += 4) 1026 EN_WRITE(sc, MID_BUFOFF+cnt, 0); /* zero memory */ |
1027#ifdef NBURSTS 1028 for (cnt = 0 ; cnt < 64*NBURSTS; cnt++) 1029#else |
|
940 for (cnt = 0 ; cnt < 68 ; cnt++) | 1030 for (cnt = 0 ; cnt < 68 ; cnt++) |
1031#endif |
|
941 dp[cnt] = 0; 942 943 if (wmtry) { 944 count = (sc->bestburstlen - sizeof(u_int32_t)) / sizeof(u_int32_t); 945 bcode = en_dmaplan[count].bcode; 946 count = wmtry >> en_dmaplan[count].divshift; 947 } else { 948 bcode = en_sz2b(lcv); 949 count = 1; 950 } | 1032 dp[cnt] = 0; 1033 1034 if (wmtry) { 1035 count = (sc->bestburstlen - sizeof(u_int32_t)) / sizeof(u_int32_t); 1036 bcode = en_dmaplan[count].bcode; 1037 count = wmtry >> en_dmaplan[count].divshift; 1038 } else { 1039 bcode = en_sz2b(lcv); 1040 count = 1; 1041 } |
1042#ifdef NBURSTS 1043 /* build lcv-byte-DMA x NBURSTS */ |
|
951 if (sc->is_adaptec) | 1044 if (sc->is_adaptec) |
1045 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ADP(lcv*NBURSTS, 0, MID_DMA_END, 0)); 1046 else 1047 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ENI(count*NBURSTS, 0, MID_DMA_END, bcode)); 1048 EN_WRITE(sc, sc->dtq_chip+4, vtophys(sp)); 1049 EN_WRAPADD(MID_DTQOFF, MID_DTQEND, sc->dtq_chip, 8); 1050 EN_WRITE(sc, MID_DMA_WRTX, MID_DTQ_A2REG(sc->dtq_chip)); 1051 cnt = 1000; 1052 while (EN_READ(sc, MID_DMA_RDTX) != MID_DTQ_A2REG(sc->dtq_chip)) { 1053 DELAY(1); 1054 cnt--; 1055 if (cnt == 0) { 1056 printf("%s: unexpected timeout in tx DMA test\n", sc->sc_dev.dv_xname); 1057/* 1058 printf(" alignment=0x%x, burst size=%d, dma addr reg=0x%x\n", 1059 (u_long)sp & 63, lcv, EN_READ(sc, MID_DMA_ADDR)); 1060*/ 1061 return(retval); /* timeout, give up */ 1062 } 1063 } 1064#else /* !NBURSTS */ 1065 if (sc->is_adaptec) |
|
952 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ADP(lcv, 0, MID_DMA_END, 0)); 953 else 954 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ENI(count, 0, MID_DMA_END, bcode)); 955 EN_WRITE(sc, sc->dtq_chip+4, vtophys(sp)); 956 EN_WRITE(sc, MID_DMA_WRTX, MID_DTQ_A2REG(sc->dtq_chip+8)); 957 cnt = 1000; 958 while (EN_READ(sc, MID_DMA_RDTX) == MID_DTQ_A2REG(sc->dtq_chip)) { 959 DELAY(1); 960 cnt--; 961 if (cnt == 0) { 962 printf("%s: unexpected timeout in tx DMA test\n", sc->sc_dev.dv_xname); 963 return(retval); /* timeout, give up */ 964 } 965 } 966 EN_WRAPADD(MID_DTQOFF, MID_DTQEND, sc->dtq_chip, 8); | 1066 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ADP(lcv, 0, MID_DMA_END, 0)); 1067 else 1068 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ENI(count, 0, MID_DMA_END, bcode)); 1069 EN_WRITE(sc, sc->dtq_chip+4, vtophys(sp)); 1070 EN_WRITE(sc, MID_DMA_WRTX, MID_DTQ_A2REG(sc->dtq_chip+8)); 1071 cnt = 1000; 1072 while (EN_READ(sc, MID_DMA_RDTX) == MID_DTQ_A2REG(sc->dtq_chip)) { 1073 DELAY(1); 1074 cnt--; 1075 if (cnt == 0) { 1076 printf("%s: unexpected timeout in tx DMA test\n", sc->sc_dev.dv_xname); 1077 return(retval); /* timeout, give up */ 1078 } 1079 } 1080 EN_WRAPADD(MID_DTQOFF, MID_DTQEND, sc->dtq_chip, 8); |
1081#endif /* !NBURSTS */ |
|
967 reg = EN_READ(sc, MID_INTACK); 968 if ((reg & MID_INT_DMA_TX) != MID_INT_DMA_TX) { 969 printf("%s: unexpected status in tx DMA test: 0x%x\n", 970 sc->sc_dev.dv_xname, reg); 971 return(retval); 972 } 973 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* re-enable DMA (only) */ 974 975 /* "return to sender..." address is known ... */ 976 | 1082 reg = EN_READ(sc, MID_INTACK); 1083 if ((reg & MID_INT_DMA_TX) != MID_INT_DMA_TX) { 1084 printf("%s: unexpected status in tx DMA test: 0x%x\n", 1085 sc->sc_dev.dv_xname, reg); 1086 return(retval); 1087 } 1088 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* re-enable DMA (only) */ 1089 1090 /* "return to sender..." address is known ... */ 1091 |
1092#ifdef NBURSTS 1093 /* build lcv-byte-DMA x NBURSTS */ |
|
977 if (sc->is_adaptec) | 1094 if (sc->is_adaptec) |
1095 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ADP(lcv*NBURSTS, 0, MID_DMA_END, 0)); 1096 else 1097 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ENI(count*NBURSTS, 0, MID_DMA_END, bcode)); 1098 EN_WRITE(sc, sc->drq_chip+4, vtophys(dp)); 1099 EN_WRAPADD(MID_DRQOFF, MID_DRQEND, sc->drq_chip, 8); 1100 EN_WRITE(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip)); 1101 cnt = 1000; 1102 while (EN_READ(sc, MID_DMA_RDRX) != MID_DRQ_A2REG(sc->drq_chip)) { 1103 DELAY(1); 1104 cnt--; 1105 if (cnt == 0) { 1106 printf("%s: unexpected timeout in rx DMA test\n", sc->sc_dev.dv_xname); 1107 return(retval); /* timeout, give up */ 1108 } 1109 } 1110#else /* !NBURSTS */ 1111 if (sc->is_adaptec) |
|
978 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ADP(lcv, 0, MID_DMA_END, 0)); 979 else 980 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ENI(count, 0, MID_DMA_END, bcode)); 981 EN_WRITE(sc, sc->drq_chip+4, vtophys(dp)); 982 EN_WRITE(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip+8)); 983 cnt = 1000; 984 while (EN_READ(sc, MID_DMA_RDRX) == MID_DRQ_A2REG(sc->drq_chip)) { 985 DELAY(1); 986 cnt--; 987 if (cnt == 0) { 988 printf("%s: unexpected timeout in rx DMA test\n", sc->sc_dev.dv_xname); 989 return(retval); /* timeout, give up */ 990 } 991 } 992 EN_WRAPADD(MID_DRQOFF, MID_DRQEND, sc->drq_chip, 8); | 1112 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ADP(lcv, 0, MID_DMA_END, 0)); 1113 else 1114 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ENI(count, 0, MID_DMA_END, bcode)); 1115 EN_WRITE(sc, sc->drq_chip+4, vtophys(dp)); 1116 EN_WRITE(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip+8)); 1117 cnt = 1000; 1118 while (EN_READ(sc, MID_DMA_RDRX) == MID_DRQ_A2REG(sc->drq_chip)) { 1119 DELAY(1); 1120 cnt--; 1121 if (cnt == 0) { 1122 printf("%s: unexpected timeout in rx DMA test\n", sc->sc_dev.dv_xname); 1123 return(retval); /* timeout, give up */ 1124 } 1125 } 1126 EN_WRAPADD(MID_DRQOFF, MID_DRQEND, sc->drq_chip, 8); |
1127#endif /* !NBURSTS */ |
|
993 reg = EN_READ(sc, MID_INTACK); 994 if ((reg & MID_INT_DMA_RX) != MID_INT_DMA_RX) { 995 printf("%s: unexpected status in rx DMA test: 0x%x\n", 996 sc->sc_dev.dv_xname, reg); 997 return(retval); 998 } 999 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* re-enable DMA (only) */ 1000 1001 if (wmtry) { 1002 return(bcmp(sp, dp, wmtry)); /* wmtry always exits here, no looping */ 1003 } 1004 | 1128 reg = EN_READ(sc, MID_INTACK); 1129 if ((reg & MID_INT_DMA_RX) != MID_INT_DMA_RX) { 1130 printf("%s: unexpected status in rx DMA test: 0x%x\n", 1131 sc->sc_dev.dv_xname, reg); 1132 return(retval); 1133 } 1134 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* re-enable DMA (only) */ 1135 1136 if (wmtry) { 1137 return(bcmp(sp, dp, wmtry)); /* wmtry always exits here, no looping */ 1138 } 1139 |
1140#ifdef NBURSTS 1141 if (bcmp(sp, dp, lcv * NBURSTS)) { 1142/* printf("DMA test failed! lcv=%d, sp=0x%x, dp=0x%x\n", lcv, sp, dp); */ 1143 return(retval); /* failed, use last value */ 1144 } 1145#else |
|
1005 if (bcmp(sp, dp, lcv)) 1006 return(retval); /* failed, use last value */ | 1146 if (bcmp(sp, dp, lcv)) 1147 return(retval); /* failed, use last value */ |
1148#endif |
|
1007 1008 retval = lcv; 1009 1010 } 1011 return(retval); /* studly 64 byte DMA present! oh baby!! */ 1012} 1013 1014/***********************************************************************/ --- 10 unchanged lines hidden (view full) --- 1025 1026STATIC int en_ioctl(ifp, cmd, data) 1027 1028struct ifnet *ifp; 1029EN_IOCTL_CMDT cmd; 1030caddr_t data; 1031 1032{ | 1149 1150 retval = lcv; 1151 1152 } 1153 return(retval); /* studly 64 byte DMA present! oh baby!! */ 1154} 1155 1156/***********************************************************************/ --- 10 unchanged lines hidden (view full) --- 1167 1168STATIC int en_ioctl(ifp, cmd, data) 1169 1170struct ifnet *ifp; 1171EN_IOCTL_CMDT cmd; 1172caddr_t data; 1173 1174{ |
1033#ifdef MISSING_IF_SOFTC 1034 struct en_softc *sc = (struct en_softc *) en_cd.cd_devs[ifp->if_unit]; 1035#else | |
1036 struct en_softc *sc = (struct en_softc *) ifp->if_softc; | 1175 struct en_softc *sc = (struct en_softc *) ifp->if_softc; |
1037#endif | |
1038 struct ifaddr *ifa = (struct ifaddr *) data; 1039 struct ifreq *ifr = (struct ifreq *) data; 1040 struct atm_pseudoioctl *api = (struct atm_pseudoioctl *)data; 1041#ifdef NATM 1042 struct atm_rawioctl *ario = (struct atm_rawioctl *)data; 1043 int slot; 1044#endif 1045 int s, error = 0; --- 28 unchanged lines hidden (view full) --- 1074 printf("%s: rxvci%d: turn %s raw (boodi) mode\n", 1075 sc->sc_dev.dv_xname, ario->npcb->npcb_vci, 1076 (ario->rawvalue) ? "on" : "off"); 1077#endif 1078 break; 1079#endif 1080 case SIOCSIFADDR: 1081 ifp->if_flags |= IFF_UP; | 1176 struct ifaddr *ifa = (struct ifaddr *) data; 1177 struct ifreq *ifr = (struct ifreq *) data; 1178 struct atm_pseudoioctl *api = (struct atm_pseudoioctl *)data; 1179#ifdef NATM 1180 struct atm_rawioctl *ario = (struct atm_rawioctl *)data; 1181 int slot; 1182#endif 1183 int s, error = 0; --- 28 unchanged lines hidden (view full) --- 1212 printf("%s: rxvci%d: turn %s raw (boodi) mode\n", 1213 sc->sc_dev.dv_xname, ario->npcb->npcb_vci, 1214 (ario->rawvalue) ? "on" : "off"); 1215#endif 1216 break; 1217#endif 1218 case SIOCSIFADDR: 1219 ifp->if_flags |= IFF_UP; |
1082#ifdef INET 1083 if (ifa->ifa_addr->sa_family == AF_INET) { | 1220#if defined(INET) || defined(INET6) 1221 if (ifa->ifa_addr->sa_family == AF_INET 1222 || ifa->ifa_addr->sa_family == AF_INET6) { |
1084 en_reset(sc); 1085 en_init(sc); 1086 ifa->ifa_rtrequest = atm_rtrequest; /* ??? */ 1087 break; 1088 } 1089#endif /* INET */ 1090 /* what to do if not INET? */ 1091 en_reset(sc); --- 24 unchanged lines hidden (view full) --- 1116#endif 1117 ifp->if_mtu = ifr->ifr_mtu; 1118 /* XXXCDC: do we really need to reset on MTU size change? */ 1119 en_reset(sc); 1120 en_init(sc); 1121 break; 1122#endif /* SIOCSIFMTU */ 1123 | 1223 en_reset(sc); 1224 en_init(sc); 1225 ifa->ifa_rtrequest = atm_rtrequest; /* ??? */ 1226 break; 1227 } 1228#endif /* INET */ 1229 /* what to do if not INET? */ 1230 en_reset(sc); --- 24 unchanged lines hidden (view full) --- 1255#endif 1256 ifp->if_mtu = ifr->ifr_mtu; 1257 /* XXXCDC: do we really need to reset on MTU size change? */ 1258 en_reset(sc); 1259 en_init(sc); 1260 break; 1261#endif /* SIOCSIFMTU */ 1262 |
1263#ifdef ATM_PVCEXT 1264 case SIOCSPVCTX: 1265 if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) == 0) 1266 error = en_pvctx(sc, (struct pvctxreq *)data); 1267 break; 1268 1269 case SIOCGPVCTX: 1270 error = en_pvctxget(sc, (struct pvctxreq *)data); 1271 break; 1272 1273 case SIOCSPVCSIF: 1274 do { 1275 struct ifnet *shadow; 1276 1277 if (error = suser(curproc->p_ucred, &curproc->p_acflag)) 1278 break; 1279 1280 if ((shadow = pvc_attach(ifp)) != NULL) { 1281 sprintf(ifr->ifr_name, "%s%d", 1282 shadow->if_name, shadow->if_unit); 1283 } 1284 else 1285 error = ENOBUFS; 1286 } while (0); 1287 break; 1288 1289#endif /* ATM_PVCEXT */ 1290 |
|
1124 default: 1125 error = EINVAL; 1126 break; 1127 } 1128 splx(s); 1129 return error; 1130} 1131 --- 159 unchanged lines hidden (view full) --- 1291 m_freem(m); 1292 } 1293 while (1) { 1294 IF_DEQUEUE(&sc->txslot[lcv].q, m); 1295 if (m == NULL) 1296 break; /* >>> exit 'while(1)' here <<< */ 1297 m_freem(m); 1298 } | 1291 default: 1292 error = EINVAL; 1293 break; 1294 } 1295 splx(s); 1296 return error; 1297} 1298 --- 159 unchanged lines hidden (view full) --- 1458 m_freem(m); 1459 } 1460 while (1) { 1461 IF_DEQUEUE(&sc->txslot[lcv].q, m); 1462 if (m == NULL) 1463 break; /* >>> exit 'while(1)' here <<< */ 1464 m_freem(m); 1465 } |
1466 |
|
1299 sc->txslot[lcv].mbsize = 0; 1300 } 1301 1302 return; 1303} 1304 1305 1306/* --- 23 unchanged lines hidden (view full) --- 1330 sc->enif.if_flags |= IFF_RUNNING; /* enable */ 1331 1332 if (sc->en_busreset) 1333 sc->en_busreset(sc); 1334 EN_WRITE(sc, MID_RESID, 0x0); /* reset */ 1335 1336 /* 1337 * init obmem data structures: vc tab, dma q's, slist. | 1467 sc->txslot[lcv].mbsize = 0; 1468 } 1469 1470 return; 1471} 1472 1473 1474/* --- 23 unchanged lines hidden (view full) --- 1498 sc->enif.if_flags |= IFF_RUNNING; /* enable */ 1499 1500 if (sc->en_busreset) 1501 sc->en_busreset(sc); 1502 EN_WRITE(sc, MID_RESID, 0x0); /* reset */ 1503 1504 /* 1505 * init obmem data structures: vc tab, dma q's, slist. |
1506 * 1507 * note that we set drq_free/dtq_free to one less than the total number 1508 * of DTQ/DRQs present. we do this because the card uses the condition 1509 * (drq_chip == drq_us) to mean "list is empty"... but if you allow the 1510 * circular list to be completely full then (drq_chip == drq_us) [i.e. 1511 * the drq_us pointer will wrap all the way around]. by restricting 1512 * the number of active requests to (N - 1) we prevent the list from 1513 * becoming completely full. note that the card will sometimes give 1514 * us an interrupt for a DTQ/DRQ we have already processes... this helps 1515 * keep that interrupt from messing us up. |
|
1338 */ 1339 1340 for (vc = 0 ; vc < MID_N_VC ; vc++) 1341 en_loadvc(sc, vc); 1342 1343 bzero(&sc->drq, sizeof(sc->drq)); | 1516 */ 1517 1518 for (vc = 0 ; vc < MID_N_VC ; vc++) 1519 en_loadvc(sc, vc); 1520 1521 bzero(&sc->drq, sizeof(sc->drq)); |
1344#if 1 1345 /* leave one entry in the ringbuf unused to avoid wraparound */ 1346 sc->drq_free = MID_DRQ_N - 1; 1347#else 1348 sc->drq_free = MID_DRQ_N; 1349#endif | 1522 sc->drq_free = MID_DRQ_N - 1; /* N - 1 */ |
1350 sc->drq_chip = MID_DRQ_REG2A(EN_READ(sc, MID_DMA_RDRX)); 1351 EN_WRITE(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip)); 1352 /* ensure zero queue */ 1353 sc->drq_us = sc->drq_chip; 1354 1355 bzero(&sc->dtq, sizeof(sc->dtq)); | 1523 sc->drq_chip = MID_DRQ_REG2A(EN_READ(sc, MID_DMA_RDRX)); 1524 EN_WRITE(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip)); 1525 /* ensure zero queue */ 1526 sc->drq_us = sc->drq_chip; 1527 1528 bzero(&sc->dtq, sizeof(sc->dtq)); |
1356#if 1 1357 /* leave one entry in the ringbuf unused to avoid wraparound */ 1358 sc->dtq_free = MID_DTQ_N - 1; 1359#else 1360 sc->dtq_free = MID_DTQ_N; 1361#endif | 1529 sc->dtq_free = MID_DTQ_N - 1; /* N - 1 */ |
1362 sc->dtq_chip = MID_DTQ_REG2A(EN_READ(sc, MID_DMA_RDTX)); 1363 EN_WRITE(sc, MID_DMA_WRTX, MID_DRQ_A2REG(sc->dtq_chip)); 1364 /* ensure zero queue */ 1365 sc->dtq_us = sc->dtq_chip; 1366 1367 sc->hwslistp = MID_SL_REG2A(EN_READ(sc, MID_SERV_WRITE)); 1368 sc->swsl_size = sc->swsl_head = sc->swsl_tail = 0; 1369 --- 68 unchanged lines hidden (view full) --- 1438 * if there is one. note that atm_output() has already splimp()'d us. 1439 */ 1440 1441STATIC void en_start(ifp) 1442 1443struct ifnet *ifp; 1444 1445{ | 1530 sc->dtq_chip = MID_DTQ_REG2A(EN_READ(sc, MID_DMA_RDTX)); 1531 EN_WRITE(sc, MID_DMA_WRTX, MID_DRQ_A2REG(sc->dtq_chip)); 1532 /* ensure zero queue */ 1533 sc->dtq_us = sc->dtq_chip; 1534 1535 sc->hwslistp = MID_SL_REG2A(EN_READ(sc, MID_SERV_WRITE)); 1536 sc->swsl_size = sc->swsl_head = sc->swsl_tail = 0; 1537 --- 68 unchanged lines hidden (view full) --- 1606 * if there is one. note that atm_output() has already splimp()'d us. 1607 */ 1608 1609STATIC void en_start(ifp) 1610 1611struct ifnet *ifp; 1612 1613{ |
1446#ifdef MISSING_IF_SOFTC 1447 struct en_softc *sc = (struct en_softc *) en_cd.cd_devs[ifp->if_unit]; 1448#else | |
1449 struct en_softc *sc = (struct en_softc *) ifp->if_softc; | 1614 struct en_softc *sc = (struct en_softc *) ifp->if_softc; |
1450#endif | |
1451 struct ifqueue *ifq = &ifp->if_snd; /* if INPUT QUEUE */ 1452 struct mbuf *m, *lastm, *prev; 1453 struct atm_pseudohdr *ap, *new_ap; 1454 int txchan, mlen, got, need, toadd, cellcnt, first; 1455 u_int32_t atm_vpi, atm_vci, atm_flags, *dat, aal; 1456 u_int8_t *cp; 1457 1458 if ((ifp->if_flags & IFF_RUNNING) == 0) --- 19 unchanged lines hidden (view full) --- 1478 * after this loop mlen total length of mbuf chain (including atm_ph), 1479 * and lastm is a pointer to the last mbuf on the chain. 1480 */ 1481 1482 lastm = m; 1483 mlen = 0; 1484 prev = NULL; 1485 while (1) { | 1615 struct ifqueue *ifq = &ifp->if_snd; /* if INPUT QUEUE */ 1616 struct mbuf *m, *lastm, *prev; 1617 struct atm_pseudohdr *ap, *new_ap; 1618 int txchan, mlen, got, need, toadd, cellcnt, first; 1619 u_int32_t atm_vpi, atm_vci, atm_flags, *dat, aal; 1620 u_int8_t *cp; 1621 1622 if ((ifp->if_flags & IFF_RUNNING) == 0) --- 19 unchanged lines hidden (view full) --- 1642 * after this loop mlen total length of mbuf chain (including atm_ph), 1643 * and lastm is a pointer to the last mbuf on the chain. 1644 */ 1645 1646 lastm = m; 1647 mlen = 0; 1648 prev = NULL; 1649 while (1) { |
1486#ifdef EN_FIXMBUF 1487 /* if eni, always fix misaligned mbuf */ 1488 if (!sc->is_adaptec || EN_NOTXDMA || !en_dma) { 1489#else 1490 if (EN_NOTXDMA || !en_dma) { /* no DMA? */ 1491#endif | 1650 /* no DMA? */ 1651 if ((!sc->is_adaptec && EN_ENIDMAFIX) || EN_NOTXDMA || !en_dma) { |
1492 if ( (mtod(lastm, unsigned long) % sizeof(u_int32_t)) != 0 || 1493 ((lastm->m_len % sizeof(u_int32_t)) != 0 && lastm->m_next)) { 1494 first = (lastm == m); 1495 if (en_mfix(sc, &lastm, prev) == 0) { /* failed? */ 1496 m_freem(m); 1497 m = NULL; 1498 break; 1499 } 1500 if (first) 1501 m = lastm; /* update */ 1502 } 1503 prev = lastm; 1504 } | 1652 if ( (mtod(lastm, unsigned long) % sizeof(u_int32_t)) != 0 || 1653 ((lastm->m_len % sizeof(u_int32_t)) != 0 && lastm->m_next)) { 1654 first = (lastm == m); 1655 if (en_mfix(sc, &lastm, prev) == 0) { /* failed? */ 1656 m_freem(m); 1657 m = NULL; 1658 break; 1659 } 1660 if (first) 1661 m = lastm; /* update */ 1662 } 1663 prev = lastm; 1664 } |
1665 |
|
1505 mlen += lastm->m_len; 1506 if (lastm->m_next == NULL) 1507 break; 1508 lastm = lastm->m_next; 1509 } 1510 1511 if (m == NULL) /* happens only if mfix fails */ 1512 continue; --- 106 unchanged lines hidden (view full) --- 1619 printf("%s: tx%d: VPI=%d, VCI=%d, FLAGS=0x%x, speed=0x%x\n", 1620 sc->sc_dev.dv_xname, txchan, atm_vpi, atm_vci, atm_flags, 1621 sc->txspeed[atm_vci]); 1622 printf(" adjusted mlen=%d, mbsize=%d\n", mlen, 1623 sc->txslot[txchan].mbsize); 1624#endif 1625 1626 IF_ENQUEUE(&sc->txslot[txchan].q, m); | 1666 mlen += lastm->m_len; 1667 if (lastm->m_next == NULL) 1668 break; 1669 lastm = lastm->m_next; 1670 } 1671 1672 if (m == NULL) /* happens only if mfix fails */ 1673 continue; --- 106 unchanged lines hidden (view full) --- 1780 printf("%s: tx%d: VPI=%d, VCI=%d, FLAGS=0x%x, speed=0x%x\n", 1781 sc->sc_dev.dv_xname, txchan, atm_vpi, atm_vci, atm_flags, 1782 sc->txspeed[atm_vci]); 1783 printf(" adjusted mlen=%d, mbsize=%d\n", mlen, 1784 sc->txslot[txchan].mbsize); 1785#endif 1786 1787 IF_ENQUEUE(&sc->txslot[txchan].q, m); |
1788 |
|
1627 en_txdma(sc, txchan); 1628 1629 } 1630 /*NOTREACHED*/ 1631} 1632 1633 1634/* 1635 * en_mfix: fix a stupid mbuf 1636 */ | 1789 en_txdma(sc, txchan); 1790 1791 } 1792 /*NOTREACHED*/ 1793} 1794 1795 1796/* 1797 * en_mfix: fix a stupid mbuf 1798 */ |
1799 1800#ifndef __FreeBSD__ 1801 1802STATIC int en_mfix(sc, mm, prev) 1803 1804struct en_softc *sc; 1805struct mbuf **mm, *prev; 1806 1807{ 1808 struct mbuf *m, *new; 1809 u_char *d, *cp; 1810 int off; 1811 struct mbuf *nxt; 1812 1813 m = *mm; 1814 1815 EN_COUNT(sc->mfix); /* count # of calls */ 1816#ifdef EN_DEBUG 1817 printf("%s: mfix mbuf m_data=%p, m_len=%d\n", sc->sc_dev.dv_xname, 1818 m->m_data, m->m_len); 1819#endif 1820 1821 d = mtod(m, u_char *); 1822 off = ((unsigned long) d) % sizeof(u_int32_t); 1823 1824 if (off) { 1825 if ((m->m_flags & M_EXT) == 0) { 1826 bcopy(d, d - off, m->m_len); /* ALIGN! (with costly data copy...) */ 1827 d -= off; 1828 m->m_data = (caddr_t)d; 1829 } else { 1830 /* can't write to an M_EXT mbuf since it may be shared */ 1831 MGET(new, M_DONTWAIT, MT_DATA); 1832 if (!new) { 1833 EN_COUNT(sc->mfixfail); 1834 return(0); 1835 } 1836 MCLGET(new, M_DONTWAIT); 1837 if ((new->m_flags & M_EXT) == 0) { 1838 m_free(new); 1839 EN_COUNT(sc->mfixfail); 1840 return(0); 1841 } 1842 bcopy(d, new->m_data, m->m_len); /* ALIGN! (with costly data copy...) */ 1843 new->m_len = m->m_len; 1844 new->m_next = m->m_next; 1845 if (prev) 1846 prev->m_next = new; 1847 m_free(m); 1848 *mm = m = new; /* note: 'd' now invalid */ 1849 } 1850 } 1851 1852 off = m->m_len % sizeof(u_int32_t); 1853 if (off == 0) 1854 return(1); 1855 1856 d = mtod(m, u_char *) + m->m_len; 1857 off = sizeof(u_int32_t) - off; 1858 1859 nxt = m->m_next; 1860 while (off--) { 1861 for ( ; nxt != NULL && nxt->m_len == 0 ; nxt = nxt->m_next) 1862 /*null*/; 1863 if (nxt == NULL) { /* out of data, zero fill */ 1864 *d++ = 0; 1865 continue; /* next "off" */ 1866 } 1867 cp = mtod(nxt, u_char *); 1868 *d++ = *cp++; 1869 m->m_len++; 1870 nxt->m_len--; 1871 nxt->m_data = (caddr_t)cp; 1872 } 1873 return(1); 1874} 1875 1876#else /* __FreeBSD__ */ 1877 |
|
1637STATIC int en_makeexclusive(struct en_softc *, struct mbuf **, struct mbuf *); 1638 1639STATIC int en_makeexclusive(sc, mm, prev) 1640 struct en_softc *sc; 1641 struct mbuf **mm, *prev; 1642{ 1643 struct mbuf *m, *new; 1644 --- 111 unchanged lines hidden (view full) --- 1756 nxt->m_len--; 1757 nxt->m_data = (caddr_t)cp; 1758 } 1759 if (nxt != NULL && nxt->m_len == 0) 1760 m->m_next = m_free(nxt); 1761 return(1); 1762} 1763 | 1878STATIC int en_makeexclusive(struct en_softc *, struct mbuf **, struct mbuf *); 1879 1880STATIC int en_makeexclusive(sc, mm, prev) 1881 struct en_softc *sc; 1882 struct mbuf **mm, *prev; 1883{ 1884 struct mbuf *m, *new; 1885 --- 111 unchanged lines hidden (view full) --- 1997 nxt->m_len--; 1998 nxt->m_data = (caddr_t)cp; 1999 } 2000 if (nxt != NULL && nxt->m_len == 0) 2001 m->m_next = m_free(nxt); 2002 return(1); 2003} 2004 |
2005#endif /* __FreeBSD__ */ |
|
1764 1765/* 1766 * en_txdma: start trasmit DMA, if possible 1767 */ 1768 1769STATIC void en_txdma(sc, chan) 1770 1771struct en_softc *sc; --- 152 unchanged lines hidden (view full) --- 1924 launch.tbd2 = MID_TBD_MK2(launch.atm_vci, 0, 0); 1925 } 1926 if ((launch.atm_flags & EN_OBTRL) == 0 && launch.aal == MID_TBD_AAL5) { 1927 EN_COUNT(sc->ltail); 1928 launch.pdu1 = MID_PDU_MK1(0, 0, datalen); /* host byte order */ 1929 } 1930 1931 en_txlaunch(sc, chan, &launch); | 2006 2007/* 2008 * en_txdma: start trasmit DMA, if possible 2009 */ 2010 2011STATIC void en_txdma(sc, chan) 2012 2013struct en_softc *sc; --- 152 unchanged lines hidden (view full) --- 2166 launch.tbd2 = MID_TBD_MK2(launch.atm_vci, 0, 0); 2167 } 2168 if ((launch.atm_flags & EN_OBTRL) == 0 && launch.aal == MID_TBD_AAL5) { 2169 EN_COUNT(sc->ltail); 2170 launch.pdu1 = MID_PDU_MK1(0, 0, datalen); /* host byte order */ 2171 } 2172 2173 en_txlaunch(sc, chan, &launch); |
1932 | 2174 2175#if NBPFILTER > 0 2176 if (sc->enif.if_bpf) { 2177 /* 2178 * adjust the top of the mbuf to skip the pseudo atm header 2179 * (and TBD, if present) before passing the packet to bpf, 2180 * restore it afterwards. 2181 */ 2182 int size = sizeof(struct atm_pseudohdr); 2183 if (launch.atm_flags & EN_OBHDR) 2184 size += MID_TBD_SIZE; 2185 2186 launch.t->m_data += size; 2187 launch.t->m_len -= size; 2188 2189 BPF_MTAP(&sc->enif, launch.t); 2190 2191 launch.t->m_data -= size; 2192 launch.t->m_len += size; 2193 } 2194#endif /* NBPFILTER > 0 */ |
1933 /* 1934 * do some housekeeping and get the next packet 1935 */ 1936 1937 sc->txslot[chan].bfree -= launch.need; 1938 IF_ENQUEUE(&sc->txslot[chan].indma, launch.t); 1939 goto again; 1940 --- 472 unchanged lines hidden (view full) --- 2413#ifdef EN_DEBUG 2414 printf("%s: tx%d: free %d dma bytes, mbsize now %d\n", 2415 sc->sc_dev.dv_xname, slot, EN_DQ_LEN(dtq), 2416 sc->txslot[slot].mbsize); 2417#endif 2418 m_freem(m); 2419 } 2420 EN_WRAPADD(0, MID_DTQ_N, idx, 1); | 2195 /* 2196 * do some housekeeping and get the next packet 2197 */ 2198 2199 sc->txslot[chan].bfree -= launch.need; 2200 IF_ENQUEUE(&sc->txslot[chan].indma, launch.t); 2201 goto again; 2202 --- 472 unchanged lines hidden (view full) --- 2675#ifdef EN_DEBUG 2676 printf("%s: tx%d: free %d dma bytes, mbsize now %d\n", 2677 sc->sc_dev.dv_xname, slot, EN_DQ_LEN(dtq), 2678 sc->txslot[slot].mbsize); 2679#endif 2680 m_freem(m); 2681 } 2682 EN_WRAPADD(0, MID_DTQ_N, idx, 1); |
2421 } | 2683 }; |
2422 sc->dtq_chip = MID_DTQ_REG2A(val); /* sync softc */ 2423 } 2424 2425 2426 /* 2427 * kick xmit channels as needed 2428 */ 2429 --- 55 unchanged lines hidden (view full) --- 2485 ATM_PH_FLAGS(&ah) = sc->rxslot[slot].atm_flags; 2486 ATM_PH_VPI(&ah) = 0; 2487 ATM_PH_SETVCI(&ah, sc->rxslot[slot].atm_vci); 2488#ifdef EN_DEBUG 2489 printf("%s: rx%d: rxvci%d: atm_input, mbuf %p, len %d, hand %p\n", 2490 sc->sc_dev.dv_xname, slot, sc->rxslot[slot].atm_vci, m, 2491 EN_DQ_LEN(drq), sc->rxslot[slot].rxhand); 2492#endif | 2684 sc->dtq_chip = MID_DTQ_REG2A(val); /* sync softc */ 2685 } 2686 2687 2688 /* 2689 * kick xmit channels as needed 2690 */ 2691 --- 55 unchanged lines hidden (view full) --- 2747 ATM_PH_FLAGS(&ah) = sc->rxslot[slot].atm_flags; 2748 ATM_PH_VPI(&ah) = 0; 2749 ATM_PH_SETVCI(&ah, sc->rxslot[slot].atm_vci); 2750#ifdef EN_DEBUG 2751 printf("%s: rx%d: rxvci%d: atm_input, mbuf %p, len %d, hand %p\n", 2752 sc->sc_dev.dv_xname, slot, sc->rxslot[slot].atm_vci, m, 2753 EN_DQ_LEN(drq), sc->rxslot[slot].rxhand); 2754#endif |
2755#if NBPFILTER > 0 2756 if (sc->enif.if_bpf) 2757 BPF_MTAP(&sc->enif, m); 2758#endif /* NBPFILTER > 0 */ 2759 |
|
2493 sc->enif.if_ipackets++; 2494 2495 atm_input(&sc->enif, &ah, m, sc->rxslot[slot].rxhand); 2496 } 2497 2498 } 2499 EN_WRAPADD(0, MID_DRQ_N, idx, 1); | 2760 sc->enif.if_ipackets++; 2761 2762 atm_input(&sc->enif, &ah, m, sc->rxslot[slot].rxhand); 2763 } 2764 2765 } 2766 EN_WRAPADD(0, MID_DRQ_N, idx, 1); |
2500 } | 2767 }; |
2501 sc->drq_chip = MID_DRQ_REG2A(val); /* sync softc */ 2502 2503 if (sc->need_drqs) { /* true if we had a DRQ shortage */ 2504 need_softserv = 1; 2505 sc->need_drqs = 0; 2506#ifdef EN_DEBUG 2507 printf("%s: cleared need DRQ condition\n", sc->sc_dev.dv_xname); 2508#endif --- 35 unchanged lines hidden (view full) --- 2544 sc->rxslot[slot].oth_flags |= ENOTHER_SWSL; 2545 sc->swslist[sc->swsl_tail] = slot; 2546 EN_WRAPADD(0, MID_SL_N, sc->swsl_tail, 1); 2547 sc->swsl_size++; 2548#ifdef EN_DEBUG 2549 printf("%s: added VCI %d to swslist\n", sc->sc_dev.dv_xname, vci); 2550#endif 2551 } | 2768 sc->drq_chip = MID_DRQ_REG2A(val); /* sync softc */ 2769 2770 if (sc->need_drqs) { /* true if we had a DRQ shortage */ 2771 need_softserv = 1; 2772 sc->need_drqs = 0; 2773#ifdef EN_DEBUG 2774 printf("%s: cleared need DRQ condition\n", sc->sc_dev.dv_xname); 2775#endif --- 35 unchanged lines hidden (view full) --- 2811 sc->rxslot[slot].oth_flags |= ENOTHER_SWSL; 2812 sc->swslist[sc->swsl_tail] = slot; 2813 EN_WRAPADD(0, MID_SL_N, sc->swsl_tail, 1); 2814 sc->swsl_size++; 2815#ifdef EN_DEBUG 2816 printf("%s: added VCI %d to swslist\n", sc->sc_dev.dv_xname, vci); 2817#endif 2818 } |
2552 } | 2819 }; |
2553 } 2554 2555 /* 2556 * now service (function too big to include here) 2557 */ 2558 2559 if (need_softserv) 2560 en_service(sc); --- 122 unchanged lines hidden (view full) --- 2683 rbd = EN_READ(sc, cur); 2684 if (MID_RBD_ID(rbd) != MID_RBD_STDID) 2685 panic("en_service: id mismatch\n"); 2686 2687 if (rbd & MID_RBD_T) { 2688 mlen = 0; /* we've got trash */ 2689 fill = MID_RBD_SIZE; 2690 EN_COUNT(sc->ttrash); | 2820 } 2821 2822 /* 2823 * now service (function too big to include here) 2824 */ 2825 2826 if (need_softserv) 2827 en_service(sc); --- 122 unchanged lines hidden (view full) --- 2950 rbd = EN_READ(sc, cur); 2951 if (MID_RBD_ID(rbd) != MID_RBD_STDID) 2952 panic("en_service: id mismatch\n"); 2953 2954 if (rbd & MID_RBD_T) { 2955 mlen = 0; /* we've got trash */ 2956 fill = MID_RBD_SIZE; 2957 EN_COUNT(sc->ttrash); |
2958#ifdef EN_DEBUG 2959 printf("RX overflow lost %d cells!\n", MID_RBD_CNT(rbd)); 2960#endif |
|
2691 } else if (!aal5) { 2692 mlen = MID_RBD_SIZE + MID_CHDR_SIZE + MID_ATMDATASZ; /* 1 cell (ick!) */ 2693 fill = 0; 2694 } else { 2695 tlen = (MID_RBD_CNT(rbd) * MID_ATMDATASZ) + MID_RBD_SIZE; 2696 pdu = cur + tlen - MID_PDU_SIZE; 2697 if (pdu >= stop) 2698 pdu -= (EN_RXSZ*1024); 2699 pdu = EN_READ(sc, pdu); /* get PDU in correct byte order */ 2700 fill = tlen - MID_RBD_SIZE - MID_PDU_LEN(pdu); 2701 if (fill < 0 || (rbd & MID_RBD_CRCERR) != 0) { | 2961 } else if (!aal5) { 2962 mlen = MID_RBD_SIZE + MID_CHDR_SIZE + MID_ATMDATASZ; /* 1 cell (ick!) */ 2963 fill = 0; 2964 } else { 2965 tlen = (MID_RBD_CNT(rbd) * MID_ATMDATASZ) + MID_RBD_SIZE; 2966 pdu = cur + tlen - MID_PDU_SIZE; 2967 if (pdu >= stop) 2968 pdu -= (EN_RXSZ*1024); 2969 pdu = EN_READ(sc, pdu); /* get PDU in correct byte order */ 2970 fill = tlen - MID_RBD_SIZE - MID_PDU_LEN(pdu); 2971 if (fill < 0 || (rbd & MID_RBD_CRCERR) != 0) { |
2702 printf("%s: invalid AAL5 PDU length or CRC detected, dropping frame\n", 2703 sc->sc_dev.dv_xname); 2704 printf("%s: got %d cells (%d bytes), AAL5 len is %d bytes (pdu=0x%x) CRCERR=%d\n", 2705 sc->sc_dev.dv_xname, MID_RBD_CNT(rbd), tlen - MID_RBD_SIZE, 2706 MID_PDU_LEN(pdu), pdu, (rbd & MID_RBD_CRCERR)?1:0); | 2972 printf("%s: %s, dropping frame\n", sc->sc_dev.dv_xname, 2973 (rbd & MID_RBD_CRCERR) ? "CRC error" : "invalid AAL5 PDU length"); 2974 printf("%s: got %d cells (%d bytes), AAL5 len is %d bytes (pdu=0x%x)\n", 2975 sc->sc_dev.dv_xname, MID_RBD_CNT(rbd), tlen - MID_RBD_SIZE, 2976 MID_PDU_LEN(pdu), pdu); |
2707 fill = tlen; 2708 } 2709 mlen = tlen - fill; 2710 } 2711 2712 } 2713 2714 /* --- 442 unchanged lines hidden (view full) --- 3157 3158 if (level & END_SWSL) { 3159 printf(" swslist [size=%d]: ", sc->swsl_size); 3160 for (cnt = sc->swsl_head ; cnt != sc->swsl_tail ; 3161 cnt = (cnt + 1) % MID_SL_N) 3162 printf("0x%x ", sc->swslist[cnt]); 3163 printf("\n"); 3164 } | 2977 fill = tlen; 2978 } 2979 mlen = tlen - fill; 2980 } 2981 2982 } 2983 2984 /* --- 442 unchanged lines hidden (view full) --- 3427 3428 if (level & END_SWSL) { 3429 printf(" swslist [size=%d]: ", sc->swsl_size); 3430 for (cnt = sc->swsl_head ; cnt != sc->swsl_tail ; 3431 cnt = (cnt + 1) % MID_SL_N) 3432 printf("0x%x ", sc->swslist[cnt]); 3433 printf("\n"); 3434 } |
3165 | |
3166 } 3167 return(0); 3168} 3169 3170/* 3171 * en_dumpmem: dump the memory 3172 */ 3173 --- 20 unchanged lines hidden (view full) --- 3194 reg = EN_READ(sc, addr); 3195 printf("mem[0x%x] = 0x%x\n", addr, reg); 3196 addr += 4; 3197 } 3198 return(0); 3199} 3200#endif 3201 | 3435 } 3436 return(0); 3437} 3438 3439/* 3440 * en_dumpmem: dump the memory 3441 */ 3442 --- 20 unchanged lines hidden (view full) --- 3463 reg = EN_READ(sc, addr); 3464 printf("mem[0x%x] = 0x%x\n", addr, reg); 3465 addr += 4; 3466 } 3467 return(0); 3468} 3469#endif 3470 |
3471#ifdef ATM_PVCEXT 3472/* 3473 * ATM PVC extention: shaper control and pvc shadow interfaces 3474 */ |
|
3202 | 3475 |
3476/* txspeed conversion derived from linux drivers/atm/eni.c 3477 by Werner Almesberger, EPFL LRC */ 3478static const int pre_div[] = { 4,16,128,2048 }; 3479 3480static int en_pcr2txspeed(pcr) 3481 int pcr; 3482{ 3483 int pre, res, div; 3484 3485 if (pcr == 0 || pcr > 347222) 3486 pre = res = 0; /* max rate */ 3487 else { 3488 for (pre = 0; pre < 3; pre++) 3489 if (25000000/pre_div[pre]/64 <= pcr) 3490 break; 3491 div = pre_div[pre]*(pcr); 3492#if 1 3493 /* 3494 * the shaper value should be rounded down, 3495 * instead of rounded up. 3496 * (which means "res" should be rounded up.) 3497 */ 3498 res = (25000000 + div -1)/div - 1; 3499#else 3500 res = 25000000/div-1; 3501#endif 3502 if (res < 0) 3503 res = 0; 3504 if (res > 63) 3505 res = 63; 3506 } 3507 return ((pre << 6) + res); 3508} 3509 3510static int en_txspeed2pcr(txspeed) 3511 int txspeed; 3512{ 3513 int pre, res, pcr; 3514 3515 pre = (txspeed >> 6) & 0x3; 3516 res = txspeed & 0x3f; 3517 pcr = 25000000 / pre_div[pre] / (res+1); 3518 return (pcr); 3519} 3520 3521/* 3522 * en_txctl selects a hardware transmit channel and sets the shaper value. 3523 * en_txctl should be called after enabling the vc by en_rxctl 3524 * since it assumes a transmit channel is already assigned by en_rxctl 3525 * to the vc. 3526 */ 3527static int en_txctl(sc, vci, joint_vci, pcr) 3528 struct en_softc *sc; 3529 int vci; 3530 int joint_vci; 3531 int pcr; 3532{ 3533 int txspeed, txchan, c, s; 3534 3535 if (pcr) 3536 txspeed = en_pcr2txspeed(pcr); 3537 else 3538 txspeed = 0; 3539 3540 s = splimp(); 3541 txchan = sc->txvc2slot[vci]; 3542 sc->txslot[txchan].nref--; 3543 3544 /* select a slot */ 3545 if (joint_vci != 0) 3546 /* use the same channel */ 3547 txchan = sc->txvc2slot[joint_vci]; 3548 if (pcr == 0) 3549 txchan = 0; 3550 else { 3551 for (c = 1, txchan = 1; c < EN_NTX; c++) { 3552 if (sc->txslot[c].nref < sc->txslot[txchan].nref) 3553 txchan = c; 3554 if (sc->txslot[txchan].nref == 0) 3555 break; 3556 } 3557 } 3558 sc->txvc2slot[vci] = txchan; 3559 sc->txslot[txchan].nref++; 3560 3561 /* set the shaper parameter */ 3562 sc->txspeed[vci] = (u_int8_t)txspeed; 3563 3564 splx(s); 3565#ifdef EN_DEBUG 3566 printf("VCI:%d PCR set to %d, tx channel %d\n", vci, pcr, txchan); 3567 if (joint_vci != 0) 3568 printf(" slot shared with VCI:%d\n", joint_vci); 3569#endif 3570 return (0); 3571} 3572 3573static int en_pvctx(sc, pvcreq) 3574 struct en_softc *sc; 3575 struct pvctxreq *pvcreq; 3576{ 3577 struct ifnet *ifp; 3578 struct atm_pseudoioctl api; 3579 struct atm_pseudohdr *pvc_aph, *pvc_joint; 3580 int vci, joint_vci, pcr; 3581 int error = 0; 3582 3583 /* check vpi:vci values */ 3584 pvc_aph = &pvcreq->pvc_aph; 3585 pvc_joint = &pvcreq->pvc_joint; 3586 3587 vci = ATM_PH_VCI(pvc_aph); 3588 joint_vci = ATM_PH_VCI(pvc_joint); 3589 pcr = pvcreq->pvc_pcr; 3590 3591 if (ATM_PH_VPI(pvc_aph) != 0 || vci >= MID_N_VC || 3592 ATM_PH_VPI(pvc_joint) != 0 || joint_vci >= MID_N_VC) 3593 return (EADDRNOTAVAIL); 3594 3595 if ((ifp = ifunit(pvcreq->pvc_ifname)) == NULL) 3596 return (ENXIO); 3597 3598 if (pcr < 0) { 3599 /* negative pcr means disable the vc. */ 3600 if (sc->rxvc2slot[vci] == RX_NONE) 3601 /* already disabled */ 3602 return 0; 3603 3604 ATM_PH_FLAGS(&api.aph) = 0; 3605 ATM_PH_VPI(&api.aph) = 0; 3606 ATM_PH_SETVCI(&api.aph, vci); 3607 api.rxhand = NULL; 3608 3609 error = en_rxctl(sc, &api, 0); 3610 3611 if (error == 0 && &sc->enif != ifp) { 3612 /* clear vc info of shadow interface */ 3613 ATM_PH_SETVCI(&api.aph, 0); 3614 pvc_setaph(ifp, &api.aph); 3615 } 3616 return (error); 3617 } 3618 3619 if (&sc->enif == ifp) { 3620 /* called for an en interface */ 3621 if (sc->rxvc2slot[vci] == RX_NONE) { 3622 /* vc is not active */ 3623 printf("%s%d: en_pvctx: rx not active! vci=%d\n", 3624 ifp->if_name, ifp->if_unit, vci); 3625 return (EINVAL); 3626 } 3627 } 3628 else { 3629 /* called for a shadow interface */ 3630 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { 3631 printf("en_pvctx: if %s is not point-to-point!\n", 3632 pvcreq->pvc_ifname); 3633 return (EINVAL); 3634 } 3635 sprintf(pvcreq->pvc_ifname, "%s%d", 3636 sc->enif.if_name, sc->enif.if_unit); 3637 3638 ATM_PH_FLAGS(&api.aph) = ATM_PH_PVCSIF | 3639 (ATM_PH_FLAGS(pvc_aph) & (ATM_PH_AAL5|ATM_PH_LLCSNAP)); 3640 ATM_PH_VPI(&api.aph) = 0; 3641 ATM_PH_SETVCI(&api.aph, vci); 3642 api.rxhand = ifp; 3643 pvc_setaph(ifp, &api.aph); 3644 3645 if (sc->rxvc2slot[vci] == RX_NONE) { 3646 /* vc is not active, enable rx */ 3647 error = en_rxctl(sc, &api, 1); 3648 if (error) 3649 return error; 3650 } 3651 else { 3652 /* vc is already active, update aph in softc */ 3653 sc->rxslot[sc->rxvc2slot[vci]].atm_flags = 3654 ATM_PH_FLAGS(&api.aph); 3655 } 3656 3657 } 3658 3659 error = en_txctl(sc, vci, joint_vci, pcr); 3660 3661 if (error == 0) { 3662 if (sc->txspeed[vci] != 0) 3663 pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]); 3664 else 3665 pvcreq->pvc_pcr = 0; 3666 } 3667 3668 return error; 3669} 3670 3671static int en_pvctxget(sc, pvcreq) 3672 struct en_softc *sc; 3673 struct pvctxreq *pvcreq; 3674{ 3675 struct atm_pseudohdr *pvc_aph; 3676 int vci, slot; 3677 3678 pvc_aph = &pvcreq->pvc_aph; 3679 vci = ATM_PH_VCI(pvc_aph); 3680 3681 if ((slot = sc->rxvc2slot[vci]) == RX_NONE) { 3682 /* vc is not active */ 3683 ATM_PH_FLAGS(pvc_aph) = 0; 3684 pvcreq->pvc_pcr = -1; 3685 } 3686 else { 3687 ATM_PH_FLAGS(pvc_aph) = sc->rxslot[slot].atm_flags; 3688 ATM_PH_VPI(pvc_aph) = 0; 3689 ATM_PH_SETVCI(pvc_aph, vci); 3690 if (sc->txspeed[vci]) 3691 pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]); 3692 else 3693 pvcreq->pvc_pcr = 0; 3694 } 3695 3696 return (0); 3697} 3698 3699#endif /* ATM_PVCEXT */ 3700 |
|
3203#endif /* NEN > 0 || !defined(__FreeBSD__) */ | 3701#endif /* NEN > 0 || !defined(__FreeBSD__) */ |