diff -urN ../sys/alpha/conf/ALTQ ./alpha/conf/ALTQ --- ../sys/alpha/conf/ALTQ Thu Jan 1 09:00:00 1970 +++ ./alpha/conf/ALTQ Fri Apr 18 00:02:03 2003 @@ -0,0 +1,211 @@ +# +# GENERIC -- Generic kernel configuration file for FreeBSD/alpha +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../i386/conf/LINT configuration file. +# If you are in doubt as to the purpose or necessity of a line, check first +# in LINT. Please note that this is the i386 LINT, but it still contains +# valuable info for alpha too +# +# For hardware specific information check HARDWARE.TXT +# +# $FreeBSD: src/sys/alpha/conf/GENERIC,v 1.71.2.26 2003/03/03 23:12:48 gallatin Exp $ + +machine alpha +cpu EV4 +cpu EV5 +ident ALTQ +maxusers 0 + +#makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +# Platforms supported +options API_UP1000 # UP1000 (Nautilus) +options DEC_AXPPCI_33 # UDB, Multia, AXPpci33, NoName +options DEC_EB164 # EB164, PC164, PC164LX, PC164SX +options DEC_EB64PLUS # EB64+, AlphaPC64, Aspen Alpine, etc +options DEC_2100_A50 # AlphaStation 200, 250, 255, 400 +options DEC_2100_A500 # AlphaServer 2000, 2100, 2100A +options DEC_KN20AA # AlphaStation 500, 600 +options DEC_ST550 # Personal Workstation 433, 500, 600 +options DEC_ST6600 # XP1000, DP264, DS20, DS10, family +options DEC_3000_300 # DEC3000/300* Pelic* family +options DEC_3000_500 # DEC3000/[4-9]00 Flamingo/Sandpiper family +options DEC_1000A # AlphaServer 1000, 1000A, 800 +options DEC_KN8AE # AlphaServer 8200/8400 (Turbolaser) +options DEC_KN300 # AlphaServer 4100 (Rawhide), 1200 (Tincup) + +options INET #InterNETworking +options INET6 #IPv6 communications protocols +options FFS #Berkeley Fast Filesystem +options FFS_ROOT #FFS usable as root device [keep this!] +options SOFTUPDATES #Enable FFS soft updates support +options UFS_DIRHASH #Improve performance on big directories +options MFS #Memory Filesystem +options MD_ROOT #MD is a potential root device +options NFS #Network Filesystem +options NFS_ROOT #NFS usable as root device +options MSDOSFS #MSDOS Filesystem +options CD9660 #ISO 9660 Filesystem +options CD9660_ROOT #CD-ROM usable as root device +options PROCFS #Process filesystem +options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!] +options SCSI_DELAY=15000 #Delay (in ms) before probing SCSI +options UCONSOLE #Allow users to grab the console +options KTRACE #ktrace(1) syscall trace support +options SYSVSHM #SYSV-style shared memory +options SYSVMSG #SYSV-style message queues +options SYSVSEM #SYSV-style semaphores +options P1003_1B #Posix P1003_1B real-time extentions +options _KPOSIX_PRIORITY_SCHEDULING +options ICMP_BANDLIM #Rate limit bad replies + +# Standard busses +device isa +device pci + +# Floppy drives +device fdc0 at isa? port IO_FD1 irq 6 drq 2 +device fd0 at fdc0 drive 0 + +# ATA and ATAPI devices +device ata +device atadisk # ATA disk drives +device atapicd # ATAPI CDROM drives +device atapifd # ATAPI floppy drives +device atapist # ATAPI tape drives + +# SCSI Controllers +device ahc # AHA2940 and onboard AIC7xxx devices +#device esp # 53C94 & friends, not CAM-ified +device isp # Qlogic family +device mpt # LSI-Logic MPT/Fusion +device ncr # NCR/Symbios Logic +device sym # NCR/Symbios Logic (newer chipsets) + +# SCSI peripherals +device scbus # SCSI bus (required) +device da # Direct Access (disks) +device sa # Sequential Access (tape etc) +device cd # CD +device pass # Passthrough device (direct SCSI access) + +# RAID controllers +device amr # AMI MegaRAID +device mlx # Mylex DAC960 family + +# atkbdc0 controls both the keyboard and the PS/2 mouse +device atkbdc0 at isa? port IO_KBD +device atkbd0 at atkbdc? irq 1 +device psm0 at atkbdc? irq 12 + +device vga0 at isa? + +# splash screen/screen saver +pseudo-device splash + +# syscons is the default console driver, resembling an SCO console +device sc0 at isa? + +# real time clock +device mcclock0 at isa? port 0x70 + +# Serial (COM) ports (required) +device sio0 at isa? port IO_COM1 irq 4 +device sio1 at isa? port IO_COM2 irq 3 + +# Parallel port +device ppc0 at isa? irq 7 +device ppbus # Parallel port bus (required) +device lpt # Printer +device ppi # Parallel port interface device +#device vpo # Requires scbus and da + +# PCI Ethernet NICs. +device de # DEC/Intel DC21x4x (``Tulip'') +device txp # 3Com 3cR990 (``Typhoon'') +device le # Lance + +# PCI Ethernet NICs that use the common MII bus controller code. +device miibus # MII bus support +device dc # DEC/Intel 21143 and workalikes +device fxp # Intel EtherExpress PRO/100B (82557, 82558) +device pcn # AMD Am79C97x PCI 10/100 NICs +device rl # RealTek 8129/8139 +device sf # Adaptec AIC-6915 (``Starfire'') +device sis # Silicon Integrated Systems SiS 900/SiS 7016 +device ste # Sundance ST201 (D-Link DFE-550TX) +device tl # Texas Instruments ThunderLAN +device vr # VIA Rhine, Rhine II +device wb # Winbond W89C840F +device wx # Intel Gigabit Ethernet Card (``Wiseman'') +device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') + +# Pseudo devices - the number indicates how many units to allocated. +pseudo-device loop # Network loopback +pseudo-device ether # Ethernet support +pseudo-device sl 1 # Kernel SLIP +pseudo-device ppp 1 # Kernel PPP +pseudo-device tun # Packet tunnel. +pseudo-device pty # Pseudo-ttys (telnet etc) +pseudo-device md # Memory "disks" +pseudo-device gif # IPv6 and IPv4 tunneling +pseudo-device faith 1 # IPv6-to-IPv4 relaying/(translation) + +# The `bpf' pseudo-device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +pseudo-device bpf #Berkeley packet filter + +# USB support +# (if you add any USB devices to this list, they must be added to the Alpha +# section of src/release/scripts/dokern.sh) +device uhci # UHCI PCI->USB interface +device ohci # OHCI PCI->USB interface +device usb # USB Bus (required) +device ugen # Generic +device uhid # "Human Interface Devices" +device ukbd # Keyboard +device ulpt # Printer +device umass # Disks/Mass storage - Requires scbus and da0 +device ums # Mouse +# USB Ethernet +device aue # ADMtek USB ethernet +device cue # CATC USB ethernet +device kue # Kawasaki LSI USB ethernet + +# ALTQ options +options ALTQ #alternate queueing +#options ALTQ_CBQ #class based queueing +#options ALTQ_WFQ #weighted fair queueing +#options ALTQ_FIFOQ #fifo queueing +#options ALTQ_RED #random early detection +#options ALTQ_FLOWVALVE #flowvalve for RED (needs RED) +#options ALTQ_RIO #triple red for diffserv (needs RED) +#options ALTQ_LOCALQ #local use +#options ALTQ_HFSC #hierarchical fair service curve +#options ALTQ_JOBS #joint buffer management and scheduling +#options ALTQ_IPSEC #check ipsec in IPv4 +#options ALTQ_CDNR #diffserv traffic conditioner +#options ALTQ_BLUE #blue by wu-chang feng +#options ALTQ_PRIQ #priority queue +#options ALTQ_NOPCC #don't use processor cycle counter +#options ALTQ_DEBUG #for debugging +# you might want to set kernel timer to 1kHz if you use CBQ, +# especially with 100baseT +#options HZ=1000 + +# options added for ALTQ +#options MROUTING # Multicast routing +#pseudo-device atm +#device en +#options NATM #native mode atm diff -urN ../sys/conf/files ./conf/files --- ../sys/conf/files Sat Mar 29 05:05:11 2003 +++ ./conf/files Thu Apr 17 22:35:57 2003 @@ -56,6 +56,21 @@ compile-with "perl5 $S/kern/makeops.pl -h $S/kern/bus_if.m" \ no-obj no-implicit-rule before-depend \ clean "bus_if.h" +altq/altq_afmap.c optional altq +altq/altq_blue.c optional altq +altq/altq_cbq.c optional altq +altq/altq_cdnr.c optional altq +altq/altq_conf.c optional altq +altq/altq_fifoq.c optional altq +altq/altq_hfsc.c optional altq +altq/altq_jobs.c optional altq +altq/altq_localq.c optional altq +altq/altq_priq.c optional altq +altq/altq_red.c optional altq +altq/altq_rio.c optional altq +altq/altq_rmclass.c optional altq +altq/altq_subr.c optional altq +altq/altq_wfq.c optional altq coda/coda_namecache.c optional vcoda coda/coda_fbsd.c optional vcoda coda/coda_psdev.c optional vcoda diff -urN ../sys/conf/options ./conf/options --- ../sys/conf/options Sat Mar 29 06:26:40 2003 +++ ./conf/options Thu Apr 17 22:35:57 2003 @@ -244,6 +244,25 @@ ATA_STATIC_ID opt_ata.h # Net stuff. +# altq stuff +ALTQ opt_global.h +ALTQ_CBQ opt_altq.h +ALTQ_WFQ opt_altq.h +ALTQ_AFMAP opt_altq.h +ALTQ_FIFOQ opt_altq.h +ALTQ_RED opt_altq.h +ALTQ_FLOWVALVE opt_altq.h +ALTQ_RIO opt_altq.h +ALTQ_IPSEC opt_altq.h +ALTQ_LOCALQ opt_altq.h +ALTQ_HFSC opt_altq.h +ALTQ_JOBS opt_altq.h +ALTQ_CDNR opt_altq.h +ALTQ_BLUE opt_altq.h +ALTQ_PRIQ opt_altq.h +ALTQ_NOPCC opt_altq.h +ALTQ_DEBUG opt_altq.h + ACCEPT_FILTER_DATA ACCEPT_FILTER_HTTP BOOTP opt_bootp.h diff -urN ../sys/dev/an/if_an.c ./dev/an/if_an.c --- ../sys/dev/an/if_an.c Tue Feb 11 12:32:48 2003 +++ ./dev/an/if_an.c Fri Apr 18 01:14:08 2003 @@ -759,7 +759,8 @@ ifp->if_watchdog = an_watchdog; ifp->if_init = an_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); bzero(sc->an_config.an_nodename, sizeof(sc->an_config.an_nodename)); bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename, @@ -1212,7 +1213,7 @@ /* Re-enable interrupts. */ CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS); - if ((ifp->if_flags & IFF_UP) && (ifp->if_snd.ifq_head != NULL)) + if ((ifp->if_flags & IFF_UP) && !IFQ_IS_EMPTY(&ifp->if_snd)) an_start(ifp); return; @@ -2583,12 +2584,7 @@ /* We can't send in monitor mode so toss any attempts. */ if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) { - for (;;) { - IF_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; - m_freem(m0); - } + IFQ_PURGE(&ifp->if_snd); return; } @@ -2598,7 +2594,7 @@ bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3)); while (sc->an_rdata.an_tx_ring[idx] == 0) { - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_DEQUEUE(&ifp->if_snd, m0); if (m0 == NULL) break; @@ -2652,7 +2648,7 @@ } else { /* MPI-350 */ while (sc->an_rdata.an_tx_empty || idx != sc->an_rdata.an_tx_cons) { - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_DEQUEUE(&ifp->if_snd, m0); if (m0 == NULL) { break; } @@ -2719,6 +2715,8 @@ sc->an_rdata.an_tx_empty = 0; } } + if (idx == sc->an_rdata.an_tx_prod) + return; if (m0 != NULL) ifp->if_flags |= IFF_OACTIVE; diff -urN ../sys/dev/ar/if_ar.c ./dev/ar/if_ar.c --- ../sys/dev/ar/if_ar.c Tue Jun 18 00:10:57 2002 +++ ./dev/ar/if_ar.c Thu Apr 17 22:35:57 2003 @@ -300,6 +300,7 @@ ifp->if_ioctl = arioctl; ifp->if_start = arstart; ifp->if_watchdog = arwatchdog; + IFQ_SET_READY(&ifp->if_snd); sc->ifsppp.pp_flags = PP_KEEPALIVE; diff -urN ../sys/dev/awi/awi.c ./dev/awi/awi.c --- ../sys/dev/awi/awi.c Fri Jan 24 06:06:42 2003 +++ ./dev/awi/awi.c Thu Apr 17 22:35:57 2003 @@ -307,10 +307,11 @@ #endif #ifdef __FreeBSD__ ifp->if_output = ether_output; - ifp->if_snd.ifq_maxlen = ifqmaxlen; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); memcpy(sc->sc_ec.ac_enaddr, sc->sc_mib_addr.aMAC_Address, ETHER_ADDR_LEN); #endif + IFQ_SET_READY(&ifp->if_snd); printf("%s: IEEE802.11 %s %dMbps (firmware %s)\n", sc->sc_dev.dv_xname, @@ -883,12 +884,7 @@ break; m_freem(m); } - for (;;) { - IF_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - m_freem(m); - } + IFQ_PURGE(&ifp->if_snd); while ((bp = TAILQ_FIRST(&sc->sc_scan)) != NULL) { TAILQ_REMOVE(&sc->sc_scan, bp, list); free(bp, M_DEVBUF); @@ -967,7 +963,7 @@ } else { if (!(ifp->if_flags & IFF_RUNNING)) break; - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_POLL(&ifp->if_snd, m0); if (m0 == NULL) break; len = m0->m_pkthdr.len + sizeof(struct ieee80211_frame); @@ -978,10 +974,10 @@ len += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN; if (awi_next_txd(sc, len, &frame, &ntxd)) { - IF_PREPEND(&ifp->if_snd, m0); ifp->if_flags |= IFF_OACTIVE; break; } + IFQ_DEQUEUE(&ifp->if_snd, m0); AWI_BPF_MTAP(sc, m0, AWI_BPF_NORM); m0 = awi_fix_txhdr(sc, m0); if (sc->sc_wep_algo != NULL && m0 != NULL) diff -urN ../sys/dev/bge/if_bge.c ./dev/bge/if_bge.c --- ../sys/dev/bge/if_bge.c Fri Feb 7 06:36:40 2003 +++ ./dev/bge/if_bge.c Thu Apr 17 22:35:57 2003 @@ -1678,7 +1678,8 @@ ifp->if_watchdog = bge_watchdog; ifp->if_init = bge_init; ifp->if_mtu = ETHERMTU; - ifp->if_snd.ifq_maxlen = BGE_TX_RING_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, BGE_TX_RING_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); ifp->if_hwassist = BGE_CSUM_FEATURES; ifp->if_capabilities = IFCAP_HWCSUM; ifp->if_capenable = ifp->if_capabilities; @@ -2152,7 +2153,7 @@ /* Re-enable interrupts. */ CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0); - if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) + if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd)) bge_start(ifp); return; @@ -2187,7 +2188,7 @@ sc->bge_link++; CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF); printf("bge%d: gigabit link up\n", sc->bge_unit); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) bge_start(ifp); } splx(s); @@ -2206,7 +2207,7 @@ IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) printf("bge%d: gigabit link up\n", sc->bge_unit); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) bge_start(ifp); } } @@ -2339,6 +2340,7 @@ struct bge_softc *sc; struct mbuf *m_head = NULL; u_int32_t prodidx = 0; + int pkts = 0; sc = ifp->if_softc; @@ -2348,7 +2350,7 @@ prodidx = CSR_READ_4(sc, BGE_MBX_TX_HOST_PROD0_LO); while(sc->bge_cdata.bge_tx_chain[prodidx] == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -2364,7 +2366,6 @@ m_head->m_pkthdr.csum_flags & (CSUM_DELAY_DATA)) { if ((BGE_TX_RING_CNT - sc->bge_txcnt) < m_head->m_pkthdr.csum_data + 16) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } @@ -2376,11 +2377,14 @@ * for the NIC to drain the ring. */ if (bge_encap(sc, m_head, &prodidx)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } + /* now we are committed to transmit the packet */ + IFQ_DEQUEUE(&ifp->if_snd, m_head); + pkts++; + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -2388,6 +2392,8 @@ if (ifp->if_bpf) bpf_mtap(ifp, m_head); } + if (pkts == 0) + return; /* Transmit */ CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx); diff -urN ../sys/dev/cs/if_cs.c ./dev/cs/if_cs.c --- ../sys/dev/cs/if_cs.c Fri Jan 26 05:13:48 2001 +++ ./dev/cs/if_cs.c Thu Apr 17 22:35:57 2003 @@ -596,7 +596,8 @@ ifp->if_ioctl=cs_ioctl; ifp->if_watchdog=cs_watchdog; ifp->if_init=cs_init; - ifp->if_snd.ifq_maxlen= IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); /* * MIB DATA */ @@ -956,7 +957,7 @@ if (sc->buf_len) length = sc->buf_len; else { - IF_DEQUEUE( &ifp->if_snd, m ); + IFQ_DEQUEUE( &ifp->if_snd, m ); if (m==NULL) { (void) splx(s); diff -urN ../sys/dev/ed/if_ed.c ./dev/ed/if_ed.c --- ../sys/dev/ed/if_ed.c Sat Nov 3 09:36:07 2001 +++ ./dev/ed/if_ed.c Thu Apr 17 22:35:57 2003 @@ -1602,9 +1602,10 @@ ifp->if_ioctl = ed_ioctl; ifp->if_watchdog = ed_watchdog; ifp->if_init = ed_init; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); ifp->if_linkmib = &sc->mibdata; ifp->if_linkmiblen = sizeof sc->mibdata; + IFQ_SET_READY(&ifp->if_snd); /* * XXX - should do a better job. */ @@ -2007,7 +2008,7 @@ ifp->if_flags |= IFF_OACTIVE; return; } - IF_DEQUEUE(&ifp->if_snd, m); + IFQ_DEQUEUE(&ifp->if_snd, m); if (m == 0) { /* diff -urN ../sys/dev/em/if_em.c ./dev/em/if_em.c --- ../sys/dev/em/if_em.c Sat Jan 4 03:18:55 2003 +++ ./dev/em/if_em.c Thu Apr 17 23:34:31 2003 @@ -478,18 +478,18 @@ return; s = splimp(); - while (ifp->if_snd.ifq_head != NULL) { + while (!IFQ_IS_EMPTY(&ifp->if_snd)) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; if (em_encap(adapter, m_head)) { ifp->if_flags |= IFF_OACTIVE; - IF_PREPEND(&ifp->if_snd, m_head); break; } + IFQ_DEQUEUE(&ifp->if_snd, m_head); /* Send a copy of the frame to the BPF listener */ #if __FreeBSD_version < 500000 @@ -744,7 +744,7 @@ em_enable_intr(adapter); - if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) + if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd)) em_start(ifp); return; @@ -1372,7 +1372,8 @@ ifp->if_ioctl = em_ioctl; ifp->if_start = em_start; ifp->if_watchdog = em_watchdog; - ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 1); + IFQ_SET_READY(&ifp->if_snd); #if __FreeBSD_version < 500000 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); diff -urN ../sys/dev/en/midway.c ./dev/en/midway.c --- ../sys/dev/en/midway.c Fri Jan 24 06:06:42 2003 +++ ./dev/en/midway.c Thu Apr 17 22:35:58 2003 @@ -48,6 +48,26 @@ * I would also like to thank Werner for promptly answering email and being * generally helpful. */ +/* + * 1997/12/02, major update on 1999/04/06 kjc + * new features added: + * - BPF support (link type is DLT_ATM_RFC1483) + * BPF understands only LLC/SNAP!! (because bpf can't + * handle variable link header length.) + * (bpfwrite should work if atm_pseudohdr and LLC/SNAP are prepended.) + * - support vc shaping + * - integrate IPv6 support. + * - support pvc sub interface + * + * initial work on per-pvc-interface for ipv6 was done + * by Katsushi Kobayashi of the WIDE Project. + * some of the extensions for pvc subinterfaces are merged from + * the CAIRN project written by Suresh Bhogavilli (suresh@isi.edu). + * + * code cleanup: + * - remove WMAYBE related code. ENI WMAYBE DMA doen't work. + * - remove updating if_lastchange for every packet. + */ #undef EN_DEBUG #undef EN_DEBUG_RANGE /* check ranges on en_read/en_write's? */ @@ -108,7 +128,6 @@ #endif /* EN_DEBUG */ #ifdef __FreeBSD__ -#include "en.h" /* XXX for midwayvar.h's NEN */ #include "opt_inet.h" #include "opt_natm.h" #include "opt_ddb.h" @@ -126,6 +145,7 @@ #include #endif #include +#include #include #include #include @@ -144,19 +164,15 @@ #include #endif -#if !defined(sparc) && !defined(__FreeBSD__) -#include -#endif - #if defined(__NetBSD__) || defined(__OpenBSD__) +#include #include #include -#if defined(__alpha__) -/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */ -#undef vtophys -#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va)) -#endif #elif defined(__FreeBSD__) +#include +#include +#include +#include #include /* for DELAY */ #include #include @@ -168,6 +184,22 @@ #endif /* __FreeBSD__ */ +#if defined(__alpha__) +/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */ +#undef vtophys +#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va)) +#endif + +#ifdef ATM_PVCEXT +# ifndef NATM + /* this is for __KAME__ */ +# include +# endif +# if defined(__KAME__) && defined(INET6) +# include +# endif +#endif /*ATM_PVCEXT*/ + #include "bpf.h" #if NBPF > 0 #include @@ -204,6 +236,7 @@ static int en_dma = EN_DMA; /* use DMA (switch off for dbg) */ +#ifndef __FreeBSD__ /* * autoconfig attachments */ @@ -211,6 +244,7 @@ struct cfdriver en_cd = { 0, "en", DV_IFNET, }; +#endif /* * local structures @@ -295,6 +329,17 @@ STATIC INLINE void en_write __P((struct en_softc *, u_int32_t, u_int32_t)) __attribute__ ((unused)); +#ifdef ATM_PVCEXT +static void rrp_add __P((struct en_softc *, struct ifnet *)); +static struct ifnet *en_pvcattach __P((struct ifnet *)); +static int en_txctl __P((struct en_softc *, int, int, int)); +static int en_pvctx __P((struct en_softc *, struct pvctxreq *)); +static int en_pvctxget __P((struct en_softc *, struct pvctxreq *)); +static int en_pcr2txspeed __P((int)); +static int en_txspeed2pcr __P((int)); +static struct ifnet *en_vci2ifp __P((struct en_softc *, int)); +#endif + /* * macros/inline */ @@ -310,7 +355,7 @@ * cooked read/write macros */ -#define EN_READ(SC,R) ntohl(en_read(SC,R)) +#define EN_READ(SC,R) (u_int32_t)ntohl(en_read(SC,R)) #define EN_WRITE(SC,R,V) en_write(SC,R, htonl(V)) #define EN_WRAPADD(START,STOP,CUR,VAL) { \ @@ -623,7 +668,7 @@ if ((m->m_flags & M_EXT) == 0) { m_free(m); m_freem(top); - return(NULL); /* out of mbuf clusters */ + return(NULL); /* out of mbuf clusters */ } m->m_len = MCLBYTES; } @@ -700,7 +745,7 @@ (MID_IS_SABRE(reg)) ? "sabre controller, " : "", (MID_IS_SUNI(reg)) ? "SUNI" : "Utopia", (!MID_IS_SUNI(reg) && MID_IS_UPIPE(reg)) ? " (pipelined)" : "", - (long)(sc->en_obmemsz / 1024)); + (long)sc->en_obmemsz / 1024); if (sc->is_adaptec) { if (sc->bestburstlen == 64 && sc->alburst == 0) @@ -725,6 +770,7 @@ ifp->if_ioctl = en_ioctl; ifp->if_output = atm_output; ifp->if_start = en_start; + IFQ_SET_READY(&ifp->if_snd); /* * init softc @@ -751,6 +797,9 @@ sz -= (EN_TXSZ * 1024); sc->txslot[lcv].stop = ptr; sc->txslot[lcv].nref = 0; +#ifdef ATM_PVCEXT + sc->txrrp = NULL; +#endif bzero(&sc->txslot[lcv].indma, sizeof(sc->txslot[lcv].indma)); bzero(&sc->txslot[lcv].q, sizeof(sc->txslot[lcv].q)); #ifdef EN_DEBUG @@ -822,6 +871,9 @@ #if NBPF > 0 BPFATTACH(ifp, DLT_ATM_RFC1483, sizeof(struct atmllc)); #endif +#ifdef ATM_PVCEXT + rrp_add(sc, ifp); +#endif } @@ -839,7 +891,7 @@ * p166: bestburstlen=64, alburst=0 */ -#if 1 /* __FreeBSD__ */ +#if defined(__FreeBSD__) && defined(__i386__) #define NBURSTS 3 /* number of bursts to use for dmaprobe */ #define BOUNDARY 1024 /* test misaligned dma crossing the bounday. should be n * 64. at least 64*(NBURSTS+1). @@ -932,7 +984,7 @@ * en_dmaprobe_doit: do actual testing */ -static int +STATIC int en_dmaprobe_doit(sc, sp, dp, wmtry) struct en_softc *sc; @@ -985,8 +1037,8 @@ for (lcv = 8 ; lcv <= MIDDMA_MAXBURST ; lcv = lcv * 2) { #ifdef EN_DEBUG - printf("DMA test lcv=%d, sp=0x%x, dp=0x%x, wmtry=%d\n", - lcv, sp, dp, wmtry); + printf("DMA test lcv=%d, sp=0x%lx, dp=0x%lx, wmtry=%d\n", + lcv, (unsigned long)sp, (unsigned long)dp, wmtry); #endif /* zero SRAM and dest buffer */ @@ -1184,6 +1236,9 @@ break; #endif case SIOCSIFADDR: +#if defined(INET6) && defined(SIOCSIFADDR_IN6) + case SIOCSIFADDR_IN6: +#endif ifp->if_flags |= IFF_UP; #if defined(INET) || defined(INET6) if (ifa->ifa_addr->sa_family == AF_INET @@ -1204,7 +1259,18 @@ break; case SIOCSIFFLAGS: +#ifdef ATM_PVCEXT + /* point-2-point pvc is allowed to change if_flags */ + if (((ifp->if_flags & IFF_UP) + && !(ifp->if_flags & IFF_RUNNING)) + || (!(ifp->if_flags & IFF_UP) + && (ifp->if_flags & IFF_RUNNING))) { + en_reset(sc); + en_init(sc); + } +#else error = EINVAL; +#endif break; #if defined(SIOCSIFMTU) /* ??? copied from if_de */ @@ -1228,6 +1294,110 @@ break; #endif /* SIOCSIFMTU */ +#ifdef ATM_PVCEXT + case SIOCADDMULTI: + case SIOCDELMULTI: + if (ifp == &sc->enif || ifr == 0) { + error = EAFNOSUPPORT; /* XXX */ + break; + } + switch (ifr->ifr_addr.sa_family) { +#ifdef INET + case AF_INET: + break; +#endif +#ifdef INET6 + case AF_INET6: + break; +#endif + default: + error = EAFNOSUPPORT; + break; + } + break; + + case SIOCGPVCSIF: + if (ifp != &sc->enif) { +#ifdef __NetBSD__ + strcpy(ifr->ifr_name, sc->enif.if_xname); +#else + sprintf(ifr->ifr_name, "%s%d", + sc->enif.if_name, sc->enif.if_unit); +#endif + } + else + error = EINVAL; + break; + + case SIOCSPVCSIF: + if (ifp == &sc->enif) { + struct ifnet *sifp; + +#if (__FreeBSD_version >= 400000) + if ((error = suser(curproc)) != 0) + break; +#else + if (error = suser(curproc->p_ucred, &curproc->p_acflag)) + break; +#endif + + if ((sifp = en_pvcattach(ifp)) != NULL) { +#ifdef __NetBSD__ + strcpy(ifr->ifr_name, sifp->if_xname); +#else + sprintf(ifr->ifr_name, "%s%d", + sifp->if_name, sifp->if_unit); +#endif +#if defined(__KAME__) && defined(INET6) + /* get EUI64 for PVC, from ATM hardware interface */ + in6_ifattach(sifp, ifp); +#endif + } + else + error = ENOMEM; + } + else + error = EINVAL; + break; + + case SIOCGPVCTX: + error = en_pvctxget(sc, (struct pvctxreq *)data); + break; + + case SIOCSPVCTX: +#if (__FreeBSD_version >= 400000) + if ((error = suser(curproc)) == 0) + error = en_pvctx(sc, (struct pvctxreq *)data); +#else + if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) == 0) + error = en_pvctx(sc, (struct pvctxreq *)data); +#endif + break; + + case SIOCGPVCFWD: + { + struct pvcfwdreq *req = (struct pvcfwdreq *)data; + error = pvc_set_fwd(req->pvc_ifname, req->pvc_ifname2, 2); + break; + } + + case SIOCSPVCFWD: + { + struct pvcfwdreq *req = (struct pvcfwdreq *)data; +#if (__FreeBSD_version >= 400000) + if ((error = suser(curproc)) == 0) + error = pvc_set_fwd(req->pvc_ifname, req->pvc_ifname2, + req->pvc_op); +#else + if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) == 0) + error = pvc_set_fwd(req->pvc_ifname, req->pvc_ifname2, + req->pvc_op); +#endif + break; + } + +#endif /* ATM_PVCEXT */ + default: error = EINVAL; break; @@ -1369,12 +1539,14 @@ if (m == NULL) break; /* >>> exit 'while(1)' here <<< */ m_freem(m); + IF_DROP(&sc->enif.if_snd); } while (1) { IF_DEQUEUE(&sc->rxslot[slot].q, m); if (m == NULL) break; /* >>> exit 'while(1)' here <<< */ m_freem(m); + IF_DROP(&sc->enif.if_snd); } sc->rxslot[slot].oth_flags &= ~ENOTHER_SWSL; if (sc->rxslot[slot].oth_flags & ENOTHER_DRAIN) { @@ -1403,7 +1575,6 @@ break; /* >>> exit 'while(1)' here <<< */ m_freem(m); } - sc->txslot[lcv].mbsize = 0; } @@ -1422,8 +1593,23 @@ { int vc, slot; u_int32_t loc; +#ifdef ATM_PVCEXT + struct pvcsif *pvcsif; +#endif if ((sc->enif.if_flags & IFF_UP) == 0) { +#ifdef ATM_PVCEXT + LIST_FOREACH(pvcsif, &sc->sif_list, sif_links) { + if (pvcsif->sif_if.if_flags & IFF_UP) { + /* + * down the device only when there is no active pvc subinterface. + * if there is, we have to go through the init sequence to reflect + * the software states to the device. + */ + goto up; + } + } +#endif #ifdef EN_DEBUG printf("%s: going down\n", sc->sc_dev.dv_xname); #endif @@ -1432,10 +1618,18 @@ return; } +#ifdef ATM_PVCEXT + up: +#endif #ifdef EN_DEBUG printf("%s: going up\n", sc->sc_dev.dv_xname); #endif sc->enif.if_flags |= IFF_RUNNING; /* enable */ +#ifdef ATM_PVCEXT + LIST_FOREACH(pvcsif, &sc->sif_list, sif_links) { + pvcsif->sif_if.if_flags |= IFF_RUNNING; + } +#endif if (sc->en_busreset) sc->en_busreset(sc); @@ -1492,7 +1686,7 @@ EN_WRITE(sc, MIDX_PLACE(slot), MIDX_MKPLACE(en_k2sz(EN_TXSZ), loc)); #ifdef EN_DEBUG printf("%s: tx%d: place 0x%x\n", sc->sc_dev.dv_xname, slot, - EN_READ(sc, MIDX_PLACE(slot))); + (u_int)EN_READ(sc, MIDX_PLACE(slot))); #endif } @@ -1552,7 +1746,6 @@ { struct en_softc *sc = (struct en_softc *) ifp->if_softc; - struct ifqueue *ifq = &ifp->if_snd; /* if INPUT QUEUE */ struct mbuf *m, *lastm, *prev; struct atm_pseudohdr *ap, *new_ap; int txchan, mlen, got, need, toadd, cellcnt, first; @@ -1569,7 +1762,7 @@ while (1) { - IF_DEQUEUE(ifq, m); + IFQ_DEQUEUE(&ifp->if_snd, m); if (m == NULL) return; /* EMPTY: >>> exit here <<< */ @@ -1595,6 +1788,7 @@ if (en_mfix(sc, &lastm, prev) == 0) { /* failed? */ m_freem(m); m = NULL; + sc->enif.if_oerrors++; break; } if (first) @@ -1628,6 +1822,7 @@ printf("%s: output vpi=%d, vci=%d out of card range, dropping...\n", sc->sc_dev.dv_xname, atm_vpi, atm_vci); m_freem(m); + sc->enif.if_oerrors++; continue; } @@ -1644,7 +1839,7 @@ * [including AAL5 PDU, if AAL5] */ - got = mlen - sizeof(struct atm_pseudohdr *); + got = mlen - sizeof(struct atm_pseudohdr); toadd = (aal == MID_TBD_AAL5) ? MID_PDU_SIZE : 0; /* PDU */ cellcnt = (got + toadd + (MID_ATMDATASZ - 1)) / MID_ATMDATASZ; need = cellcnt * MID_ATMDATASZ; @@ -1654,7 +1849,7 @@ printf("%s: txvci%d: mlen=%d, got=%d, need=%d, toadd=%d, cell#=%d\n", sc->sc_dev.dv_xname, atm_vci, mlen, got, need, toadd, cellcnt); printf(" leading_space=%d, trailing_space=%d\n", - M_LEADINGSPACE(m), M_TRAILINGSPACE(lastm)); + (int)M_LEADINGSPACE(m), (int)M_TRAILINGSPACE(lastm)); #endif #ifdef EN_MBUF_OPT @@ -1707,6 +1902,7 @@ if (sc->txslot[txchan].mbsize > EN_TXHIWAT) { EN_COUNT(sc->txmbovr); m_freem(m); + IF_DROP(&ifp->if_snd); #ifdef EN_DEBUG printf("%s: tx%d: buffer space shortage\n", sc->sc_dev.dv_xname, txchan); @@ -1759,7 +1955,7 @@ #endif d = mtod(m, u_char *); - off = ((unsigned long) d) % sizeof(u_int32_t); + off = ((uintptr_t) (void *) d) % sizeof(u_int32_t); if (off) { if ((m->m_flags & M_EXT) == 0) { @@ -1886,12 +2082,12 @@ EN_COUNT(sc->mfix); /* count # of calls */ #ifdef EN_DEBUG - printf("%s: mfix mbuf m_data=0x%x, m_len=%d\n", sc->sc_dev.dv_xname, + printf("%s: mfix mbuf m_data=%p, m_len=%d\n", sc->sc_dev.dv_xname, m->m_data, m->m_len); #endif d = mtod(m, u_char *); - off = ((uintptr_t) (void *) d) % sizeof(u_int32_t); + off = ((unsigned long) d) % sizeof(u_int32_t); if (off) { if ((m->m_flags & M_EXT) == 0) { @@ -2103,7 +2299,12 @@ */ EN_COUNT(sc->launch); +#ifdef ATM_PVCEXT + /* if there's a subinterface for this vci, override ifp. */ + ifp = en_vci2ifp(sc, launch.atm_vci); +#else ifp = &sc->enif; +#endif ifp->if_opackets++; if ((launch.atm_flags & EN_OBHDR) == 0) { @@ -2160,6 +2361,7 @@ if (launch.t != tmp) panic("en dequeue drop"); m_freem(launch.t); + IF_DROP(&sc->enif.if_snd); sc->txslot[chan].mbsize -= launch.mlen; goto again; } @@ -2217,8 +2419,9 @@ sc->sc_dev.dv_xname, chan, l->t, cur, (cur-start)/4, need, addtail); count = EN_READ(sc, MIDX_PLACE(chan)); printf(" HW: base_address=0x%x, size=%d, read=%d, descstart=%d\n", - MIDX_BASE(count), MIDX_SZ(count), EN_READ(sc, MIDX_READPTR(chan)), - EN_READ(sc, MIDX_DESCSTART(chan))); + (u_int)MIDX_BASE(count), MIDX_SZ(count), + (int)EN_READ(sc, MIDX_READPTR(chan)), + (int)EN_READ(sc, MIDX_DESCSTART(chan))); #endif /* @@ -2492,7 +2695,7 @@ pad -= 2; #ifdef EN_DEBUG printf("%s: tx%d: padding %d bytes (cur now 0x%x)\n", - sc->sc_dev.dv_xname, chan, pad * sizeof(u_int32_t), cur); + sc->sc_dev.dv_xname, chan, (int)(pad * sizeof(u_int32_t)), cur); #endif while (pad--) { EN_WRITEDAT(sc, cur, 0); /* no byte order issues with zero */ @@ -2705,8 +2908,15 @@ EN_DQ_LEN(drq), sc->rxslot[slot].rxhand); #endif +#ifdef ATM_PVCEXT + /* if there's a subinterface for this vci, override ifp. */ + ifp = en_vci2ifp(sc, sc->rxslot[slot].atm_vci); + ifp->if_ipackets++; + m->m_pkthdr.rcvif = ifp; /* XXX */ +#else ifp = &sc->enif; ifp->if_ipackets++; +#endif #if NBPF > 0 if (ifp->if_bpf) @@ -2796,6 +3006,28 @@ sc->vtrash += MID_VTRASH(reg); #endif +#ifdef ATM_PVCEXT + /* + * when the tx buffer is full, packets are left in the interface queue. + * (en dequeues all packets even when the tx buffer is full.) + * call en_start for each pvc interface using round-robin scheduling + * to avoid starvation. + */ + if (kick) { + struct rrp *rrp_start; + + if ((rrp_start = sc->txrrp) != NULL) { + while (1) { + en_start(sc->txrrp->ifp); + if (sc->txrrp->next == rrp_start) + break; + else + sc->txrrp = sc->txrrp->next; + } + } + } +#endif + EN_INTR_RET(1); /* for us */ } @@ -2941,7 +3173,11 @@ } fill = tlen; +#ifdef ATM_PVCEXT + ifp = en_vci2ifp(sc, vci); +#else ifp = &sc->enif; +#endif ifp->if_ierrors++; } @@ -3257,9 +3493,22 @@ struct en_softc *sc; int lcv, cnt, slot; u_int32_t ptr, reg; +#ifdef __FreeBSD__ + devclass_t dc; + int maxunit; + dc = devclass_find("en"); + if (dc == NULL) { + printf("en_dump: can't find devclass!\n"); + return 0; + } + maxunit = devclass_get_maxunit(dc); + for (lcv = 0 ; lcv < maxunit ; lcv++) { + sc = devclass_get_softc(dc, lcv); +#else for (lcv = 0 ; lcv < en_cd.cd_ndevs ; lcv++) { sc = (struct en_softc *) en_cd.cd_devs[lcv]; +#endif if (sc == NULL) continue; if (unit != -1 && unit != lcv) continue; @@ -3308,24 +3557,21 @@ if (level & END_MREGS) { printf("mregs:\n"); - printf("resid = 0x%lx\n", (u_long)EN_READ(sc, MID_RESID)); + printf("resid = 0x%x\n", EN_READ(sc, MID_RESID)); printf("interrupt status = 0x%b\n", - (int)EN_READ(sc, MID_INTSTAT), MID_INTBITS); + (int)EN_READ(sc, MID_INTSTAT), MID_INTBITS); printf("interrupt enable = 0x%b\n", - (int)EN_READ(sc, MID_INTENA), MID_INTBITS); + (int)EN_READ(sc, MID_INTENA), MID_INTBITS); printf("mcsr = 0x%b\n", (int)EN_READ(sc, MID_MAST_CSR), MID_MCSRBITS); - printf("serv_write = [chip=%ld] [us=%d]\n", - (long)EN_READ(sc, MID_SERV_WRITE), - MID_SL_A2REG(sc->hwslistp)); - printf("dma addr = 0x%lx\n", (u_long)EN_READ(sc, MID_DMA_ADDR)); - printf("DRQ: chip[rd=0x%lx,wr=0x%lx], sc[chip=0x%x,us=0x%x]\n", - (u_long)MID_DRQ_REG2A(EN_READ(sc, MID_DMA_RDRX)), - (u_long)MID_DRQ_REG2A(EN_READ(sc, MID_DMA_WRRX)), - sc->drq_chip, sc->drq_us); - printf("DTQ: chip[rd=0x%lx,wr=0x%lx], sc[chip=0x%x,us=0x%x]\n", - (u_long)MID_DTQ_REG2A(EN_READ(sc, MID_DMA_RDTX)), - (u_long)MID_DTQ_REG2A(EN_READ(sc, MID_DMA_WRTX)), - sc->dtq_chip, sc->dtq_us); + printf("serv_write = [chip=%u] [us=%u]\n", EN_READ(sc, MID_SERV_WRITE), + MID_SL_A2REG(sc->hwslistp)); + printf("dma addr = 0x%x\n", EN_READ(sc, MID_DMA_ADDR)); + printf("DRQ: chip[rd=0x%x,wr=0x%x], sc[chip=0x%x,us=0x%x]\n", + MID_DRQ_REG2A(EN_READ(sc, MID_DMA_RDRX)), + MID_DRQ_REG2A(EN_READ(sc, MID_DMA_WRRX)), sc->drq_chip, sc->drq_us); + printf("DTQ: chip[rd=0x%x,wr=0x%x], sc[chip=0x%x,us=0x%x]\n", + MID_DTQ_REG2A(EN_READ(sc, MID_DMA_RDTX)), + MID_DTQ_REG2A(EN_READ(sc, MID_DMA_WRTX)), sc->dtq_chip, sc->dtq_us); printf(" unusal txspeeds: "); for (cnt = 0 ; cnt < MID_N_VC ; cnt++) @@ -3349,11 +3595,10 @@ (sc->txslot[slot].cur - sc->txslot[slot].start)/4); printf("mbsize=%d, bfree=%d\n", sc->txslot[slot].mbsize, sc->txslot[slot].bfree); - printf("txhw: base_address=0x%lx, size=%ld, read=%ld, descstart=%ld\n", - (u_long)MIDX_BASE(EN_READ(sc, MIDX_PLACE(slot))), - (u_long)MIDX_SZ(EN_READ(sc, MIDX_PLACE(slot))), - (long)EN_READ(sc, MIDX_READPTR(slot)), - (long)EN_READ(sc, MIDX_DESCSTART(slot))); + printf("txhw: base_address=0x%x, size=%u, read=%u, descstart=%u\n", + (u_int)MIDX_BASE(EN_READ(sc, MIDX_PLACE(slot))), + MIDX_SZ(EN_READ(sc, MIDX_PLACE(slot))), + EN_READ(sc, MIDX_READPTR(slot)), EN_READ(sc, MIDX_DESCSTART(slot))); } } @@ -3366,10 +3611,10 @@ printf("mode=0x%x, atm_flags=0x%x, oth_flags=0x%x\n", sc->rxslot[slot].mode, sc->rxslot[slot].atm_flags, sc->rxslot[slot].oth_flags); - printf("RXHW: mode=0x%lx, DST_RP=0x%lx, WP_ST_CNT=0x%lx\n", - (u_long)EN_READ(sc, MID_VC(sc->rxslot[slot].atm_vci)), - (u_long)EN_READ(sc, MID_DST_RP(sc->rxslot[slot].atm_vci)), - (u_long)EN_READ(sc, MID_WP_ST_CNT(sc->rxslot[slot].atm_vci))); + printf("RXHW: mode=0x%x, DST_RP=0x%x, WP_ST_CNT=0x%x\n", + EN_READ(sc, MID_VC(sc->rxslot[slot].atm_vci)), + EN_READ(sc, MID_DST_RP(sc->rxslot[slot].atm_vci)), + EN_READ(sc, MID_WP_ST_CNT(sc->rxslot[slot].atm_vci))); } } @@ -3379,10 +3624,9 @@ ptr = sc->dtq_chip; while (ptr != sc->dtq_us) { reg = EN_READ(sc, ptr); - printf("\t0x%x=[cnt=%d, chan=%d, end=%d, type=%d @ 0x%lx]\n", + printf("\t0x%x=[cnt=%d, chan=%d, end=%d, type=%d @ 0x%x]\n", sc->dtq[MID_DTQ_A2REG(ptr)], MID_DMA_CNT(reg), MID_DMA_TXCHAN(reg), - (reg & MID_DMA_END) != 0, MID_DMA_TYPE(reg), - (u_long)EN_READ(sc, ptr+4)); + (reg & MID_DMA_END) != 0, MID_DMA_TYPE(reg), EN_READ(sc, ptr+4)); EN_WRAPADD(MID_DTQOFF, MID_DTQEND, ptr, 8); } } @@ -3393,10 +3637,9 @@ ptr = sc->drq_chip; while (ptr != sc->drq_us) { reg = EN_READ(sc, ptr); - printf("\t0x%x=[cnt=%d, chan=%d, end=%d, type=%d @ 0x%lx]\n", + printf("\t0x%x=[cnt=%d, chan=%d, end=%d, type=%d @ 0x%x]\n", sc->drq[MID_DRQ_A2REG(ptr)], MID_DMA_CNT(reg), MID_DMA_RXVCI(reg), - (reg & MID_DMA_END) != 0, MID_DMA_TYPE(reg), - (u_long)EN_READ(sc, ptr+4)); + (reg & MID_DMA_END) != 0, MID_DMA_TYPE(reg), EN_READ(sc, ptr+4)); EN_WRAPADD(MID_DRQOFF, MID_DRQEND, ptr, 8); } } @@ -3424,12 +3667,23 @@ { struct en_softc *sc; u_int32_t reg; +#ifdef __FreeBSD__ + devclass_t dc; + dc = devclass_find("en"); + if (dc == NULL) { + printf("en_dumpmem: can't find devclass!\n"); + return 0; + } + sc = devclass_get_softc(dc, unit); +#else if (unit < 0 || unit > en_cd.cd_ndevs || (sc = (struct en_softc *) en_cd.cd_devs[unit]) == NULL) { printf("invalid unit number: %d\n", unit); return(0); } +#endif + addr = addr & ~3; if (addr < MID_RAMOFF || addr + len*4 > MID_MAXOFF || len <= 0) { printf("invalid addr/len number: %d, %d\n", addr, len); @@ -3444,3 +3698,422 @@ return(0); } #endif + +#ifdef ATM_PVCEXT +/* + * ATM PVC extention: shaper control and pvc subinterfaces + */ + +/* + * the list of the interfaces sharing the physical device. + * in order to avoid starvation, the interfaces are scheduled in + * a round-robin fashion when en_start is called from tx complete + * interrupts. + */ +static void rrp_add(sc, ifp) + struct en_softc *sc; + struct ifnet *ifp; +{ + struct rrp *head, *p, *new; + + head = sc->txrrp; + if ((p = head) != NULL) { + while (1) { + if (p->ifp == ifp) { + /* an entry for this ifp already exits */ + p->nref++; + return; + } + if (p->next == head) + break; + p = p->next; + } + } + + /* create a new entry */ + MALLOC(new, struct rrp *, sizeof(struct rrp), M_DEVBUF, M_WAITOK); + if (new == NULL) { + printf("en_rrp_add: malloc failed!\n"); + return; + } + + new->ifp = ifp; + new->nref = 1; + + if (p == NULL) { + /* this is the only one in the list */ + new->next = new; + sc->txrrp = new; + } + else { + /* add the new entry at the tail of the list */ + new->next = p->next; + p->next = new; + } +} + +#if 0 /* not used */ +static void rrp_delete(sc, ifp) + struct en_softc *sc; + struct ifnet *ifp; +{ + struct rrp *head, *p, *prev; + + head = sc->txrrp; + + prev = head; + if (prev == NULL) { + printf("rrp_delete: no list!\n"); + return; + } + p = prev->next; + + while (1) { + if (p->ifp == ifp) { + p->nref--; + if (p->nref > 0) + return; + /* remove this entry */ + if (p == prev) { + /* this is the only entry in the list */ + sc->txrrp = NULL; + } + else { + prev->next = p->next; + if (head == p) + sc->txrrp = p->next; + } + FREE(p, M_DEVBUF); + } + prev = p; + p = prev->next; + if (prev == head) { + printf("rrp_delete: no matching entry!\n"); + return; + } + } +} +#endif /* 0 */ + +static struct ifnet * +en_vci2ifp(sc, vci) + struct en_softc *sc; + int vci; +{ + struct pvcsif *pvcsif; + + LIST_FOREACH(pvcsif, &sc->sif_list, sif_links) { + if (vci == pvcsif->sif_vci) + return (&pvcsif->sif_if); + } + return (&sc->enif); +} + +/* + * create and attach per pvc subinterface + * (currently detach is not supported) + */ +static struct ifnet * +en_pvcattach(ifp) + struct ifnet *ifp; +{ + struct en_softc *sc = (struct en_softc *) ifp->if_softc; + struct ifnet *pvc_ifp; + int s; + + if ((pvc_ifp = pvcsif_alloc()) == NULL) + return (NULL); + + pvc_ifp->if_softc = sc; + pvc_ifp->if_ioctl = en_ioctl; + pvc_ifp->if_start = en_start; + pvc_ifp->if_flags = (IFF_POINTOPOINT|IFF_MULTICAST) | + (ifp->if_flags & (IFF_RUNNING|IFF_SIMPLEX|IFF_NOTRAILERS)); + IFQ_SET_READY(&pvc_ifp->if_snd); + + s = splimp(); + LIST_INSERT_HEAD(&sc->sif_list, (struct pvcsif *)pvc_ifp, sif_links); + if_attach(pvc_ifp); + atm_ifattach(pvc_ifp); + +#if NBPF > 0 + BPFATTACH(pvc_ifp, DLT_ATM_RFC1483, sizeof(struct atmllc)); +#endif +#ifdef ATM_PVCEXT + rrp_add(sc, pvc_ifp); +#endif + splx(s); + + return (pvc_ifp); +} + + +/* txspeed conversion derived from linux drivers/atm/eni.c + by Werner Almesberger, EPFL LRC */ +static const int pre_div[] = { 4,16,128,2048 }; + +static int en_pcr2txspeed(pcr) + int pcr; +{ + int pre, res, div; + + if (pcr == 0 || pcr > 347222) + pre = res = 0; /* max rate */ + else { + for (pre = 0; pre < 3; pre++) + if (25000000/pre_div[pre]/64 <= pcr) + break; + div = pre_div[pre]*(pcr); +#if 1 + /* + * the shaper value should be rounded down, + * instead of rounded up. + * (which means "res" should be rounded up.) + */ + res = (25000000 + div -1)/div - 1; +#else + res = 25000000/div-1; +#endif + if (res < 0) + res = 0; + if (res > 63) + res = 63; + } + return ((pre << 6) + res); +} + +static int en_txspeed2pcr(txspeed) + int txspeed; +{ + int pre, res, pcr; + + pre = (txspeed >> 6) & 0x3; + res = txspeed & 0x3f; + pcr = 25000000 / pre_div[pre] / (res+1); + return (pcr); +} + +/* + * en_txctl selects a hardware transmit channel and sets the shaper value. + * en_txctl should be called after enabling the vc by en_rxctl + * since it assumes a transmit channel is already assigned by en_rxctl + * to the vc. + */ +static int en_txctl(sc, vci, joint_vci, pcr) + struct en_softc *sc; + int vci; + int joint_vci; + int pcr; +{ + int txspeed, txchan, s; + + if (pcr) + txspeed = en_pcr2txspeed(pcr); + else + txspeed = 0; + + s = splimp(); + txchan = sc->txvc2slot[vci]; + sc->txslot[txchan].nref--; + + /* select a slot */ + if (joint_vci != 0) + /* use the same channel */ + txchan = sc->txvc2slot[joint_vci]; + else if (pcr == 0) + txchan = 0; + else { + for (txchan = 1; txchan < EN_NTX; txchan++) { + if (sc->txslot[txchan].nref == 0) + break; + } + } + if (txchan == EN_NTX) { +#if 1 + /* no free slot! */ + splx(s); + return (ENOSPC); +#else + /* + * to allow multiple vc's to share a slot, + * use a slot with the smallest reference count + */ + int slot = 1; + txchan = 1; + for (slot = 2; slot < EN_NTX; slot++) + if (sc->txslot[slot].nref < sc->txslot[txchan].nref) + txchan = slot; +#endif + } + + sc->txvc2slot[vci] = txchan; + sc->txslot[txchan].nref++; + + /* set the shaper parameter */ + sc->txspeed[vci] = (u_int8_t)txspeed; + + splx(s); +#ifdef EN_DEBUG + printf("VCI:%d PCR set to %d, tx channel %d\n", vci, pcr, txchan); + if (joint_vci != 0) + printf(" slot shared with VCI:%d\n", joint_vci); +#endif + return (0); +} + +static int en_pvctx(sc, pvcreq) + struct en_softc *sc; + struct pvctxreq *pvcreq; +{ + struct ifnet *ifp; + struct atm_pseudoioctl api; + struct atm_pseudohdr *pvc_aph, *pvc_joint; + int vci, joint_vci, pcr; + int error = 0; + + /* check vpi:vci values */ + pvc_aph = &pvcreq->pvc_aph; + pvc_joint = &pvcreq->pvc_joint; + + vci = ATM_PH_VCI(pvc_aph); + joint_vci = ATM_PH_VCI(pvc_joint); + pcr = pvcreq->pvc_pcr; + + if (ATM_PH_VPI(pvc_aph) != 0 || vci >= MID_N_VC || + ATM_PH_VPI(pvc_joint) != 0 || joint_vci >= MID_N_VC) + return (EADDRNOTAVAIL); + + if ((ifp = ifunit(pvcreq->pvc_ifname)) == NULL) + return (ENXIO); + + if (pcr < 0) { + /* negative pcr means disable the vc. */ + if (sc->rxvc2slot[vci] == RX_NONE) + /* already disabled */ + return 0; + + ATM_PH_FLAGS(&api.aph) = 0; + ATM_PH_VPI(&api.aph) = 0; + ATM_PH_SETVCI(&api.aph, vci); + api.rxhand = NULL; + + error = en_rxctl(sc, &api, 0); + + if (error == 0 && &sc->enif != ifp) { + /* clear vc info of this subinterface */ + struct pvcsif *pvcsif = (struct pvcsif *)ifp; + + ATM_PH_SETVCI(&api.aph, 0); + pvcsif->sif_aph = api.aph; + pvcsif->sif_vci = 0; + } + return (error); + } + + if (&sc->enif == ifp) { + /* called for an en interface */ + if (sc->rxvc2slot[vci] == RX_NONE) { + /* vc is not active */ +#ifdef __NetBSD__ + printf("%s: en_pvctx: rx not active! vci=%d\n", + ifp->if_xname, vci); +#else + printf("%s%d: en_pvctx: rx not active! vci=%d\n", + ifp->if_name, ifp->if_unit, vci); +#endif + return (EINVAL); + } + } + else { + /* called for a pvc subinterface */ + struct pvcsif *pvcsif = (struct pvcsif *)ifp; + +#ifdef __NetBSD__ + strcpy(pvcreq->pvc_ifname, sc->enif.if_xname); +#else + sprintf(pvcreq->pvc_ifname, "%s%d", + sc->enif.if_name, sc->enif.if_unit); +#endif + ATM_PH_FLAGS(&api.aph) = + (ATM_PH_FLAGS(pvc_aph) & (ATM_PH_AAL5|ATM_PH_LLCSNAP)); + ATM_PH_VPI(&api.aph) = 0; + ATM_PH_SETVCI(&api.aph, vci); + api.rxhand = NULL; + pvcsif->sif_aph = api.aph; + pvcsif->sif_vci = ATM_PH_VCI(&api.aph); + + if (sc->rxvc2slot[vci] == RX_NONE) { + /* vc is not active, enable rx */ + error = en_rxctl(sc, &api, 1); + if (error) + return error; + } + else { + /* vc is already active, update aph in softc */ + sc->rxslot[sc->rxvc2slot[vci]].atm_flags = + ATM_PH_FLAGS(&api.aph); + } + } + + error = en_txctl(sc, vci, joint_vci, pcr); + + if (error == 0) { + if (sc->txspeed[vci] != 0) + pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]); + else + pvcreq->pvc_pcr = 0; + } + + return error; +} + +static int en_pvctxget(sc, pvcreq) + struct en_softc *sc; + struct pvctxreq *pvcreq; +{ + struct pvcsif *pvcsif; + struct ifnet *ifp; + int vci, slot; + + if ((ifp = ifunit(pvcreq->pvc_ifname)) == NULL) + return (ENXIO); + + if (ifp == &sc->enif) { + /* physical interface: assume vci is specified */ + struct atm_pseudohdr *pvc_aph; + + pvc_aph = &pvcreq->pvc_aph; + vci = ATM_PH_VCI(pvc_aph); + if ((slot = sc->rxvc2slot[vci]) == RX_NONE) + ATM_PH_FLAGS(pvc_aph) = 0; + else + ATM_PH_FLAGS(pvc_aph) = sc->rxslot[slot].atm_flags; + ATM_PH_VPI(pvc_aph) = 0; + } + else { + /* pvc subinterface */ +#ifdef __NetBSD__ + strcpy(pvcreq->pvc_ifname, sc->enif.if_xname); +#else + sprintf(pvcreq->pvc_ifname, "%s%d", + sc->enif.if_name, sc->enif.if_unit); +#endif + pvcsif = (struct pvcsif *)ifp; + pvcreq->pvc_aph = pvcsif->sif_aph; + vci = pvcsif->sif_vci; + } + + if ((slot = sc->rxvc2slot[vci]) == RX_NONE) { + /* vc is not active */ + ATM_PH_FLAGS(&pvcreq->pvc_aph) = 0; + pvcreq->pvc_pcr = -1; + } + else if (sc->txspeed[vci]) + pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]); + else + pvcreq->pvc_pcr = 0; + + return (0); +} + +#endif /* ATM_PVCEXT */ diff -urN ../sys/dev/en/midwayreg.h ./dev/en/midwayreg.h --- ../sys/dev/en/midwayreg.h Wed Jul 29 14:34:12 1998 +++ ./dev/en/midwayreg.h Thu Apr 17 22:35:58 2003 @@ -8,26 +8,6 @@ * */ -#if defined(sparc) || defined(__FreeBSD__) -/* XXX: gross. netbsd/sparc doesn't have machine/bus.h yet. */ -typedef void * bus_space_tag_t; -typedef u_int32_t pci_chipset_tag_t; -typedef caddr_t bus_space_handle_t; -typedef u_int32_t bus_size_t; -typedef caddr_t bus_addr_t; - -#define bus_space_read_4(t, h, o) ((void) t, \ - (*(volatile u_int32_t *)((h) + (o)))) -#define bus_space_write_4(t, h, o, v) \ - ((void) t, ((void)(*(volatile u_int32_t *)((h) + (o)) = (v)))) - -#if defined(sparc) -#define vtophys(x) ((u_int32_t)(x)) /* sun4c dvma */ -#endif - -#endif - - #define MID_SZTOB(X) ((X) * 256 * 4) /* size to bytes */ #define MID_BTOSZ(X) ((X) / 256 / 4) /* bytes to "size" */ diff -urN ../sys/dev/en/midwayvar.h ./dev/en/midwayvar.h --- ../sys/dev/en/midwayvar.h Wed Jul 29 14:34:13 1998 +++ ./dev/en/midwayvar.h Thu Apr 17 22:35:58 2003 @@ -80,14 +80,17 @@ #define DV_IFNET 1 -struct cfdriver { - int zero; - char *name; - int one; - int cd_ndevs; - void *cd_devs[NEN]; -}; +#endif +#if 1 /* for ATM_PVCEXT */ +#include + +/* round-robin scheduler */ +struct rrp { + struct rrp *next; + struct ifnet *ifp; + int nref; +}; #endif /* @@ -143,6 +146,10 @@ u_int8_t txspeed[MID_N_VC]; /* speed of tx on a VC */ u_int8_t txvc2slot[MID_N_VC]; /* map VC to slot */ +#if 1 /* for ATM_PVCEXT */ + struct rrp *txrrp; /* round-robin pointer to ifnet */ +#endif + /* recv vc ctrl. (per vc). maps VC number to recv slot */ u_int16_t rxvc2slot[MID_N_VC]; int en_nrx; /* # of active rx slots */ @@ -195,6 +202,10 @@ u_int8_t bestburstmask; /* bits to check if not multiple of burst */ u_int8_t alburst; /* align dma bursts? */ u_int8_t is_adaptec; /* adaptec version of midway? */ + +#if 1 /* for ATM_PVCEXT */ + LIST_HEAD(sif_list, pvcsif) sif_list; /* pvc subinterface list */ +#endif }; /* diff -urN ../sys/dev/ep/if_ep.c ./dev/ep/if_ep.c --- ../sys/dev/ep/if_ep.c Wed Mar 6 16:26:35 2002 +++ ./dev/ep/if_ep.c Thu Apr 17 22:35:58 2003 @@ -297,7 +297,8 @@ ifp->if_ioctl = ep_if_ioctl; ifp->if_watchdog = ep_if_watchdog; ifp->if_init = ep_if_init; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); if (!sc->epb.mii_trans) { ifmedia_init(&sc->ifmedia, 0, ep_ifmedia_upd, ep_ifmedia_sts); @@ -452,7 +453,7 @@ startagain: /* Sneak a peek at the next packet */ - m = ifp->if_snd.ifq_head; + IFQ_POLL(&ifp->if_snd, m); if (m == 0) { return; } @@ -469,7 +470,7 @@ if (len + pad > ETHER_MAX_LEN) { /* packet is obviously too large: toss it */ ++ifp->if_oerrors; - IF_DEQUEUE(&ifp->if_snd, m); + IFQ_DEQUEUE(&ifp->if_snd, m); m_freem(m); goto readcheck; } @@ -485,7 +486,7 @@ outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE); } - IF_DEQUEUE(&ifp->if_snd, m); + IFQ_DEQUEUE(&ifp->if_snd, m); s = splhigh(); @@ -533,7 +534,7 @@ * we check if we have packets left, in that case we prepare to come * back later */ - if (ifp->if_snd.ifq_head) { + if (!IFQ_IS_EMPTY(&ifp->if_snd)) { outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | 8); } return; @@ -634,7 +635,7 @@ * To have a tx_avail_int but giving the chance to the * Reception */ - if (ifp->if_snd.ifq_head) { + if (!IFQ_IS_EMPTY(&ifp->if_snd)) { outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | 8); } } diff -urN ../sys/dev/ex/if_ex.c ./dev/ex/if_ex.c --- ../sys/dev/ex/if_ex.c Mon Mar 5 14:33:20 2001 +++ ./dev/ex/if_ex.c Thu Apr 17 22:35:58 2003 @@ -241,7 +241,8 @@ ifp->if_ioctl = ex_ioctl; ifp->if_watchdog = ex_watchdog; ifp->if_init = ex_init; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); ifmedia_init(&sc->ifmedia, 0, ex_ifmedia_upd, ex_ifmedia_sts); @@ -381,8 +382,10 @@ * Main loop: send outgoing packets to network card until there are no * more packets left, or the card cannot accept any more yet. */ - while (((opkt = ifp->if_snd.ifq_head) != NULL) && - !(ifp->if_flags & IFF_OACTIVE)) { + while (!(ifp->if_flags & IFF_OACTIVE)) { + IFQ_POLL(&ifp->if_snd, opkt); + if (opkt == NULL) + break; /* * Ensure there is enough free transmit buffer space for @@ -415,7 +418,7 @@ DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail);); if (avail >= len + XMT_HEADER_LEN) { - IF_DEQUEUE(&ifp->if_snd, opkt); + IFQ_DEQUEUE(&ifp->if_snd, opkt); #ifdef EX_PSA_INTR /* @@ -605,7 +608,7 @@ * be sent, attempt to send more packets to the network card. */ - if (send_pkts && (ifp->if_snd.ifq_head != NULL)) { + if (send_pkts && !IFQ_IS_EMPTY(&ifp->if_snd)) { ex_start(ifp); } diff -urN ../sys/dev/fe/if_fe.c ./dev/fe/if_fe.c --- ../sys/dev/fe/if_fe.c Fri Sep 22 19:01:47 2000 +++ ./dev/fe/if_fe.c Thu Apr 17 22:35:58 2003 @@ -780,6 +780,7 @@ if (sc->sc_if.if_snd.ifq_maxlen == 0) sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen; #endif + IFQ_SET_READY(&sc->sc_if.if_snd); #if FE_SINGLE_TRANSMISSION /* Override txb config to allocate minimum. */ @@ -1268,7 +1269,7 @@ /* * Get the next mbuf chain for a packet to send. */ - IF_DEQUEUE(&sc->sc_if.if_snd, m); + IFQ_DEQUEUE(&sc->sc_if.if_snd, m); if (m == NULL) { /* No more packets to send. */ goto indicate_inactive; diff -urN ../sys/dev/fxp/if_fxp.c ./dev/fxp/if_fxp.c --- ../sys/dev/fxp/if_fxp.c Tue Jan 28 20:17:33 2003 +++ ./dev/fxp/if_fxp.c Thu Apr 17 22:35:58 2003 @@ -645,6 +645,7 @@ ifp->if_ioctl = fxp_ioctl; ifp->if_start = fxp_start; ifp->if_watchdog = fxp_watchdog; + IFQ_SET_READY(&ifp->if_snd); /* * Attach the interface. @@ -660,7 +661,7 @@ * Let the system queue as many packets as we have available * TX descriptors. */ - ifp->if_snd.ifq_maxlen = FXP_NTXCB - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, FXP_NTXCB - 1); splx(s); return (0); @@ -1032,14 +1033,16 @@ * NOTE: One TxCB is reserved to guarantee that fxp_mc_setup() can add * a NOP command when needed. */ - while (ifp->if_snd.ifq_head != NULL && sc->tx_queued < FXP_NTXCB - 1) { + while (!IFQ_IS_EMPTY(&ifp->if_snd) && sc->tx_queued < FXP_NTXCB - 1) { struct mbuf *m, *mb_head; int segment; /* * Grab a packet to transmit. */ - IF_DEQUEUE(&ifp->if_snd, mb_head); + IFQ_DEQUEUE(&ifp->if_snd, mb_head); + if (mb_head == NULL) + break; /* * Get pointer to next available tx desc. @@ -1150,6 +1153,11 @@ * going again if suspended. */ if (txp != NULL) { +#ifdef ALTQ + /* if tb regulator is used, we need tx complete interrupt */ + if (TBR_IS_ENABLED(&ifp->if_snd)) + txp->cb_command |= FXP_CB_COMMAND_I; +#endif fxp_scb_wait(sc); fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME); } @@ -1282,7 +1290,7 @@ /* * Try to start more packets transmitting. */ - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) fxp_start(ifp); } diff -urN ../sys/dev/gx/if_gx.c ./dev/gx/if_gx.c --- ../sys/dev/gx/if_gx.c Sat Dec 15 04:51:39 2001 +++ ./dev/gx/if_gx.c Thu Apr 17 22:35:58 2003 @@ -346,7 +346,8 @@ ifp->if_watchdog = gx_watchdog; ifp->if_init = gx_init; ifp->if_mtu = ETHERMTU; - ifp->if_snd.ifq_maxlen = GX_TX_RING_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, GX_TX_RING_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); /* see if we can enable hardware checksumming */ if (gx->gx_vflags & GXF_CSUM) { @@ -1453,7 +1454,7 @@ /* Turn interrupts on. */ CSR_WRITE_4(gx, GX_INT_MASK_SET, GX_INT_WANTED); - if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) + if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd)) gx_start(ifp); splx(s); @@ -1593,7 +1594,7 @@ gx = ifp->if_softc; for (;;) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -1603,10 +1604,11 @@ * for the NIC to drain the ring. */ if (gx_encap(gx, m_head) != 0) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } + + IFQ_DEQUEUE(&ifp->if_snd, m_head); /* * If there's a BPF listener, bounce a copy of this frame diff -urN ../sys/dev/ie/if_ie.c ./dev/ie/if_ie.c --- ../sys/dev/ie/if_ie.c Fri Mar 28 06:02:31 2003 +++ ./dev/ie/if_ie.c Thu Apr 17 23:37:34 2003 @@ -825,7 +825,8 @@ ifp->if_type = IFT_ETHER; ifp->if_addrlen = 6; ifp->if_hdrlen = 14; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); if (ie->hard_type == IE_EE16) EVENTHANDLER_REGISTER(shutdown_post_sync, ee16_shutdown, @@ -1427,7 +1428,7 @@ return; do { - IF_DEQUEUE(&ie->arpcom.ac_if.if_snd, m); + IFQ_DEQUEUE(&ie->arpcom.ac_if.if_snd, m); if (!m) break; diff -urN ../sys/dev/lge/if_lge.c ./dev/lge/if_lge.c --- ../sys/dev/lge/if_lge.c Sat Dec 15 04:49:23 2001 +++ ./dev/lge/if_lge.c Thu Apr 17 22:35:58 2003 @@ -647,7 +647,8 @@ ifp->if_watchdog = lge_watchdog; ifp->if_init = lge_init; ifp->if_baudrate = 1000000000; - ifp->if_snd.ifq_maxlen = LGE_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, LGE_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); ifp->if_capabilities = IFCAP_RXCSUM; ifp->if_capenable = ifp->if_capabilities; @@ -1194,7 +1195,7 @@ IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_TX) printf("lge%d: gigabit link up\n", sc->lge_unit); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) lge_start(ifp); } } @@ -1252,7 +1253,7 @@ /* Re-enable interrupts. */ CSR_WRITE_4(sc, LGE_IMR, LGE_IMR_SETRST_CTL0|LGE_IMR_INTR_ENB); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) lge_start(ifp); return; @@ -1318,6 +1319,7 @@ struct lge_softc *sc; struct mbuf *m_head = NULL; u_int32_t idx; + int pkts = 0; sc = ifp->if_softc; @@ -1333,16 +1335,19 @@ if (CSR_READ_1(sc, LGE_TXCMDFREE_8BIT) == 0) break; - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; if (lge_encap(sc, m_head, &idx)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } + /* now we are committed to transmit the packet */ + IFQ_DEQUEUE(&ifp->if_snd, m_head); + pkts++; + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -1350,6 +1355,8 @@ if (ifp->if_bpf) bpf_mtap(ifp, m_head); } + if (pkts == 0) + return; sc->lge_cdata.lge_tx_prod = idx; @@ -1621,7 +1628,7 @@ ifp->if_flags &= ~IFF_RUNNING; lge_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) lge_start(ifp); return; diff -urN ../sys/dev/my/if_my.c ./dev/my/if_my.c --- ../sys/dev/my/if_my.c Wed Apr 17 11:05:27 2002 +++ ./dev/my/if_my.c Thu Apr 17 22:35:58 2003 @@ -998,7 +998,8 @@ ifp->if_watchdog = my_watchdog; ifp->if_init = my_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); if (sc->my_info->my_did == MTD803ID) sc->my_pinfo = my_phys; @@ -1416,7 +1417,7 @@ /* Re-enable interrupts. */ CSR_WRITE_4(sc, MY_IMR, MY_INTRS); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) my_start(ifp); MY_UNLOCK(sc); return; @@ -1508,7 +1509,7 @@ } start_tx = sc->my_cdata.my_tx_free; while (sc->my_cdata.my_tx_free->my_mbuf == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -1803,7 +1804,7 @@ my_stop(sc); my_reset(sc); my_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) my_start(ifp); MY_LOCK(sc); return; diff -urN ../sys/dev/nge/if_nge.c ./dev/nge/if_nge.c --- ../sys/dev/nge/if_nge.c Thu Feb 6 07:03:57 2003 +++ ./dev/nge/if_nge.c Thu Apr 17 22:35:58 2003 @@ -965,7 +965,8 @@ ifp->if_watchdog = nge_watchdog; ifp->if_init = nge_init; ifp->if_baudrate = 1000000000; - ifp->if_snd.ifq_maxlen = NGE_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, NGE_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); ifp->if_hwassist = NGE_CSUM_FEATURES; ifp->if_capabilities = IFCAP_HWCSUM; ifp->if_capenable = ifp->if_capabilities; @@ -1564,7 +1565,7 @@ sc->nge_unit); nge_miibus_statchg(sc->nge_miibus); sc->nge_link++; - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) nge_start(ifp); } } @@ -1580,7 +1581,7 @@ == IFM_1000_TX) printf("nge%d: gigabit link up\n", sc->nge_unit); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) nge_start(ifp); } } @@ -1714,7 +1715,7 @@ /* Re-enable interrupts. */ CSR_WRITE_4(sc, NGE_IER, 1); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) nge_start(ifp); /* Data LED off for TBI mode */ @@ -1812,6 +1813,7 @@ struct nge_softc *sc; struct mbuf *m_head = NULL; u_int32_t idx; + int pkts = 0; sc = ifp->if_softc; @@ -1824,16 +1826,19 @@ return; while(sc->nge_ldata->nge_tx_list[idx].nge_mbuf == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; if (nge_encap(sc, m_head, &idx)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } + /* now we are committed to transmit the packet */ + IFQ_DEQUEUE(&ifp->if_snd, m_head); + pkts++; + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -1842,6 +1847,8 @@ bpf_mtap(ifp, m_head); } + if (pkts == 0) + return; /* Transmit */ sc->nge_cdata.nge_tx_prod = idx; @@ -2255,7 +2262,7 @@ ifp->if_flags &= ~IFF_RUNNING; nge_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) nge_start(ifp); return; diff -urN ../sys/dev/pdq/pdq_ifsubr.c ./dev/pdq/pdq_ifsubr.c --- ../sys/dev/pdq/pdq_ifsubr.c Thu Aug 3 07:39:30 2000 +++ ./dev/pdq/pdq_ifsubr.c Thu Apr 17 22:35:58 2003 @@ -131,13 +131,7 @@ ifp->if_flags &= ~IFF_OACTIVE; ifp->if_timer = 0; - for (;;) { - struct mbuf *m; - IF_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - return; - m_freem(m); - } + IFQ_PURGE(&ifp->if_snd); } ifnet_ret_t @@ -145,7 +139,6 @@ struct ifnet *ifp) { pdq_softc_t *sc = (pdq_softc_t *) ((caddr_t) ifp - offsetof(pdq_softc_t, sc_ac.ac_if)); - struct ifqueue *ifq = &ifp->if_snd; struct mbuf *m; int tx = 0; @@ -160,15 +153,16 @@ return; } for (;; tx = 1) { - IF_DEQUEUE(ifq, m); + IFQ_POLL(&ifp->if_snd, m); if (m == NULL) break; if (pdq_queue_transmit_data(sc->sc_pdq, m) == PDQ_FALSE) { ifp->if_flags |= IFF_OACTIVE; - IF_PREPEND(ifq, m); break; } + + IFQ_DEQUEUE(&ifp->if_snd, m); } if (tx) PDQ_DO_TYPE2_PRODUCER(sc->sc_pdq); @@ -204,7 +198,7 @@ { pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx; sc->sc_if.if_flags &= ~IFF_OACTIVE; - if (sc->sc_if.if_snd.ifq_head != NULL) { + if (!IFQ_IS_EMPTY(&sc->sc_if.if_snd)) { sc->sc_if.if_timer = PDQ_OS_TX_TIMEOUT; pdq_ifstart(&sc->sc_if); } else { @@ -373,7 +367,8 @@ ifp->if_ioctl = pdq_ifioctl; ifp->if_output = fddi_output; ifp->if_start = pdq_ifstart; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); #warning "Implement fddi_resolvemulti!" /* ifp->if_resolvemulti = ether_resolvemulti; XXX */ diff -urN ../sys/dev/ray/if_ray.c ./dev/ray/if_ray.c --- ../sys/dev/ray/if_ray.c Wed Aug 15 07:54:05 2001 +++ ./dev/ray/if_ray.c Thu Apr 17 22:35:58 2003 @@ -516,7 +516,8 @@ ifp->if_ioctl = ray_ioctl; ifp->if_watchdog = ray_watchdog; ifp->if_init = ray_init; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); ether_ifattach(ifp, ETHER_BPF_SUPPORTED); @@ -1372,12 +1373,7 @@ */ ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); ifp->if_timer = 0; - for (;;) { - IF_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - m_freem(m); - } + IFQ_PURGE(&ifp->if_snd); ray_com_runq_done(sc); } @@ -1480,7 +1476,7 @@ * Get the mbuf and process it - we have to remember to free the * ccs if there are any errors. */ - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_DEQUEUE(&ifp->if_snd, m0); if (m0 == NULL) { RAY_CCS_FREE(sc, ccs); return; @@ -1627,7 +1623,7 @@ RAY_DPRINTF(sc, RAY_DBG_SUBR, ""); - if (!(ifp->if_flags & IFF_OACTIVE) && (ifp->if_snd.ifq_head != NULL)) { + if (!(ifp->if_flags & IFF_OACTIVE) && !IFQ_IS_EMPTY(&ifp->if_snd)) { s = splimp(); ray_tx(ifp); splx(s); @@ -2491,7 +2487,7 @@ } /* Send any packets lying around and update error counters */ - if (!(ifp->if_flags & IFF_OACTIVE) && (ifp->if_snd.ifq_head != NULL)) + if (!(ifp->if_flags & IFF_OACTIVE) && !IFQ_IS_EMPTY(&ifp->if_snd)) ray_tx(ifp); if ((++sc->sc_checkcounters % 32) == 0) ray_intr_updt_errcntrs(sc); diff -urN ../sys/dev/sbni/if_sbni.c ./dev/sbni/if_sbni.c --- ../sys/dev/sbni/if_sbni.c Sun Aug 11 18:32:00 2002 +++ ./dev/sbni/if_sbni.c Thu Apr 17 22:35:58 2003 @@ -234,7 +234,8 @@ ifp->if_output = ether_output; ifp->if_ioctl = sbni_ioctl; ifp->if_watchdog = sbni_watchdog; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); /* report real baud rate */ csr0 = sbni_inb(sc, CSR0); @@ -666,7 +667,7 @@ sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND); for (;;) { - IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, sc->tx_buf_p); + IFQ_DEQUEUE(&sc->arpcom.ac_if.if_snd, sc->tx_buf_p); if (!sc->tx_buf_p) { /* nothing to transmit... */ sc->pktlen = 0; @@ -701,21 +702,13 @@ static void drop_xmit_queue(struct sbni_softc *sc) { - struct mbuf *m; - if (sc->tx_buf_p) { m_freem(sc->tx_buf_p); sc->tx_buf_p = NULL; sc->arpcom.ac_if.if_oerrors++; } - for (;;) { - IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); - if (m == NULL) - break; - m_freem(m); - sc->arpcom.ac_if.if_oerrors++; - } + IFQ_PURGE(&sc->arpcom.ac_if.if_snd); sc->tx_frameno = 0; sc->framelen = 0; diff -urN ../sys/dev/sn/if_sn.c ./dev/sn/if_sn.c --- ../sys/dev/sn/if_sn.c Sun Feb 4 13:38:38 2001 +++ ./dev/sn/if_sn.c Thu Apr 17 22:35:58 2003 @@ -222,7 +222,8 @@ ifp->if_ioctl = snioctl; ifp->if_watchdog = snwatchdog; ifp->if_init = sninit; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); ifp->if_timer = 0; ether_ifattach(ifp, ETHER_BPF_SUPPORTED); @@ -382,7 +383,7 @@ /* * Sneak a peek at the next packet */ - m = sc->arpcom.ac_if.if_snd.ifq_head; + IFQ_POLL(&sc->arpcom.ac_if.if_snd, m); if (m == 0) { splx(s); return; @@ -403,7 +404,7 @@ if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) { printf("sn%d: large packet discarded (A)\n", ifp->if_unit); ++sc->arpcom.ac_if.if_oerrors; - IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); + IFQ_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); m_freem(m); goto readcheck; } @@ -497,7 +498,7 @@ * Get the packet from the kernel. This will include the Ethernet * frame header, MAC Addresses etc. */ - IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); + IFQ_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); /* * Push out the data to the card. @@ -601,7 +602,7 @@ /* * Sneak a peek at the next packet */ - m = sc->arpcom.ac_if.if_snd.ifq_head; + IFQ_POLL(&sc->arpcom.ac_if.if_snd, m); if (m == 0) { printf("sn%d: snresume() with nothing to send\n", ifp->if_unit); return; @@ -622,7 +623,7 @@ if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) { printf("sn%d: large packet discarded (B)\n", ifp->if_unit); ++sc->arpcom.ac_if.if_oerrors; - IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); + IFQ_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); m_freem(m); return; } @@ -698,7 +699,7 @@ * Get the packet from the kernel. This will include the Ethernet * frame header, MAC Addresses etc. */ - IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); + IFQ_DEQUEUE(&sc->arpcom.ac_if.if_snd, m); /* * Push out the data to the card. diff -urN ../sys/dev/snc/dp83932.c ./dev/snc/dp83932.c --- ../sys/dev/snc/dp83932.c Tue Feb 11 17:52:00 2003 +++ ./dev/snc/dp83932.c Thu Apr 17 22:35:58 2003 @@ -193,7 +193,8 @@ ifp->if_watchdog = sncwatchdog; ifp->if_init = sncinit; ifp->if_mtu = ETHERMTU; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); bcopy(myea, sc->sc_ethercom.ac_enaddr, ETHER_ADDR_LEN); /* Initialize media goo. */ @@ -356,7 +357,7 @@ return; } - IF_DEQUEUE(&ifp->if_snd, m); + IFQ_POLL(&ifp->if_snd, m); if (m == 0) return; @@ -378,9 +379,10 @@ * it to the o/p queue. */ if ((sonicput(sc, m, mtd_next)) == 0) { - IF_PREPEND(&ifp->if_snd, m); return; } + + IFQ_DEQUEUE(&ifp->if_snd, m); sc->mtd_prev = sc->mtd_free; sc->mtd_free = mtd_next; diff -urN ../sys/dev/sr/if_sr.c ./dev/sr/if_sr.c --- ../sys/dev/sr/if_sr.c Tue Jun 18 00:10:58 2002 +++ ./dev/sr/if_sr.c Thu Apr 17 22:35:58 2003 @@ -428,6 +428,7 @@ ifp->if_ioctl = srioctl; ifp->if_start = srstart; ifp->if_watchdog = srwatchdog; + IFQ_SET_READY(&ifp->if_snd); sc->ifsppp.pp_flags = PP_KEEPALIVE; sppp_attach((struct ifnet *)&sc->ifsppp); diff -urN ../sys/dev/tx/if_tx.c ./dev/tx/if_tx.c --- ../sys/dev/tx/if_tx.c Tue Oct 29 10:43:49 2002 +++ ./dev/tx/if_tx.c Fri Apr 18 00:50:50 2003 @@ -239,7 +239,8 @@ ifp->if_init = (if_init_f_t*)epic_init; ifp->if_timer = 0; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = TX_RING_SIZE - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, TX_RING_SIZE - 1); + IFQ_SET_READY(&ifp->if_snd); /* Enable ports, memory and busmastering */ command = pci_read_config(dev, PCIR_COMMAND, 4); @@ -562,7 +563,7 @@ flist = sc->tx_flist + sc->cur_tx; /* Get next packet to send */ - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_DEQUEUE(&ifp->if_snd, m0); /* If nothing to send, return */ if (NULL == m0) return; @@ -760,7 +761,7 @@ if (status & (INTSTAT_TXC|INTSTAT_TCC|INTSTAT_TQE)) { epic_tx_done(sc); - if (sc->sc_if.if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&sc->sc_if.if_snd)) epic_ifstart(&sc->sc_if); } @@ -867,7 +868,7 @@ device_printf(sc->dev, "seems we can continue normaly\n"); /* Start output */ - if (ifp->if_snd.ifq_head) epic_ifstart(ifp); + if (!IFQ_IS_EMPTY(&ifp->if_snd)) epic_ifstart(ifp); splx(x); } diff -urN ../sys/dev/txp/if_txp.c ./dev/txp/if_txp.c --- ../sys/dev/txp/if_txp.c Sat Dec 15 04:50:43 2001 +++ ./dev/txp/if_txp.c Thu Apr 17 22:35:58 2003 @@ -351,7 +351,8 @@ ifp->if_watchdog = txp_watchdog; ifp->if_init = txp_init; ifp->if_baudrate = 100000000; - ifp->if_snd.ifq_maxlen = TX_ENTRIES; + IFQ_SET_MAXLEN(&ifp->if_snd, TX_ENTRIES); + IFQ_SET_READY(&ifp->if_snd); ifp->if_hwassist = 0; txp_capabilities(sc); @@ -1292,7 +1293,7 @@ cnt = r->r_cnt; while (1) { - IF_DEQUEUE(&ifp->if_snd, m); + IFQ_POLL(&ifp->if_snd, m); if (m == NULL) break; @@ -1361,6 +1362,9 @@ } + /* now we are committed to transmit the packet */ + IFQ_DEQUEUE(&ifp->if_snd, m); + ifp->if_timer = 5; if (ifp->if_bpf) @@ -1376,7 +1380,6 @@ ifp->if_flags |= IFF_OACTIVE; r->r_prod = firstprod; r->r_cnt = firstcnt; - IF_PREPEND(&ifp->if_snd, m); return; } diff -urN ../sys/dev/usb/if_aue.c ./dev/usb/if_aue.c --- ../sys/dev/usb/if_aue.c Thu Mar 6 02:12:22 2003 +++ ./dev/usb/if_aue.c Thu Apr 17 22:35:59 2003 @@ -743,7 +743,8 @@ ifp->if_watchdog = aue_watchdog; ifp->if_init = aue_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); /* * Do MII setup. @@ -1117,7 +1118,7 @@ if (mii->mii_media_status & IFM_ACTIVE && IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) sc->aue_link++; - if (ifp->if_snd.ifq_head != NULL) + if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) aue_start(ifp); } @@ -1185,16 +1186,17 @@ if (ifp->if_flags & IFF_OACTIVE) return; - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) return; if (aue_encap(sc, m_head, 0)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; return; } + IFQ_DEQUEUE(&ifp->if_snd, m_head); + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -1436,7 +1438,7 @@ usbd_get_xfer_status(c->aue_xfer, NULL, NULL, NULL, &stat); aue_txeof(c->aue_xfer, c, stat); - if (ifp->if_snd.ifq_head != NULL) + if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) aue_start(ifp); return; diff -urN ../sys/dev/usb/if_cue.c ./dev/usb/if_cue.c --- ../sys/dev/usb/if_cue.c Wed Nov 6 23:23:20 2002 +++ ./dev/usb/if_cue.c Thu Apr 17 22:35:59 2003 @@ -536,7 +536,8 @@ ifp->if_watchdog = cue_watchdog; ifp->if_init = cue_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); cue_qdat.ifp = ifp; cue_qdat.if_rxstart = cue_rxstart; @@ -886,16 +887,17 @@ if (ifp->if_flags & IFF_OACTIVE) return; - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) return; if (cue_encap(sc, m_head, 0)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; return; } + IFQ_DEQUEUE(&ifp->if_snd, m_head); + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -1082,7 +1084,7 @@ usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &stat); cue_txeof(c->cue_xfer, c, stat); - if (ifp->if_snd.ifq_head != NULL) + if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) cue_start(ifp); return; diff -urN ../sys/dev/usb/if_kue.c ./dev/usb/if_kue.c --- ../sys/dev/usb/if_kue.c Wed Nov 6 23:23:20 2002 +++ ./dev/usb/if_kue.c Thu Apr 17 22:35:59 2003 @@ -482,7 +482,8 @@ ifp->if_watchdog = kue_watchdog; ifp->if_init = kue_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); kue_qdat.ifp = ifp; kue_qdat.if_rxstart = kue_rxstart; @@ -806,16 +807,17 @@ if (ifp->if_flags & IFF_OACTIVE) return; - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) return; if (kue_encap(sc, m_head, 0)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; return; } + IFQ_DEQUEUE(&ifp->if_snd, m_head); + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -990,7 +992,7 @@ usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &stat); kue_txeof(c->kue_xfer, c, stat); - if (ifp->if_snd.ifq_head != NULL) + if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) kue_start(ifp); return; diff -urN ../sys/dev/usb/usb_ethersubr.c ./dev/usb/usb_ethersubr.c --- ../sys/dev/usb/usb_ethersubr.c Wed Nov 6 23:23:20 2002 +++ ./dev/usb/usb_ethersubr.c Thu Apr 17 22:35:59 2003 @@ -101,7 +101,7 @@ /* Re-arm the receiver */ (*q->if_rxstart)(ifp); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) (*ifp->if_start)(ifp); } @@ -112,7 +112,7 @@ break; ifp = m->m_pkthdr.rcvif; m_freem(m); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) (*ifp->if_start)(ifp); } diff -urN ../sys/dev/vx/if_vx.c ./dev/vx/if_vx.c --- ../sys/dev/vx/if_vx.c Wed Feb 13 09:43:10 2002 +++ ./dev/vx/if_vx.c Thu Apr 17 22:35:59 2003 @@ -201,7 +201,7 @@ ifp->if_unit = sc->unit; ifp->if_name = "vx"; ifp->if_mtu = ETHERMTU; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_output = ether_output; ifp->if_start = vxstart; @@ -209,6 +209,7 @@ ifp->if_init = vxinit; ifp->if_watchdog = vxwatchdog; ifp->if_softc = sc; + IFQ_SET_READY(&ifp->if_snd); ether_ifattach(ifp, ETHER_BPF_SUPPORTED); @@ -445,7 +446,7 @@ startagain: /* Sneak a peek at the next packet */ - m0 = ifp->if_snd.ifq_head; + IFQ_POLL(&ifp->if_snd, m0); if (m0 == 0) { return; } @@ -464,7 +465,7 @@ if (len + pad > ETHER_MAX_LEN) { /* packet is obviously too large: toss it */ ++ifp->if_oerrors; - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_DEQUEUE(&ifp->if_snd, m0); m_freem(m0); goto readcheck; } @@ -479,7 +480,7 @@ } } outw(BASE + VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2)); - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_DEQUEUE(&ifp->if_snd, m0); if (m0 == NULL) { /* not really needed */ return; } diff -urN ../sys/dev/wi/if_wi.c ./dev/wi/if_wi.c --- ../sys/dev/wi/if_wi.c Fri Aug 2 16:11:34 2002 +++ ./dev/wi/if_wi.c Thu Apr 17 22:35:59 2003 @@ -274,7 +274,8 @@ ifp->if_watchdog = wi_watchdog; ifp->if_init = wi_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); bzero(sc->wi_node_name, sizeof(sc->wi_node_name)); bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name, @@ -969,7 +970,7 @@ /* Re-enable interrupts. */ CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); - if (ifp->if_snd.ifq_head != NULL) { + if (!IFQ_IS_EMPTY(&ifp->if_snd)) { wi_start(ifp); } @@ -2263,7 +2264,7 @@ } nextpkt: - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_DEQUEUE(&ifp->if_snd, m0); if (m0 == NULL) { WI_UNLOCK(sc, s); return; diff -urN ../sys/dev/wi/wi_hostap.c ./dev/wi/wi_hostap.c --- ../sys/dev/wi/wi_hostap.c Fri Aug 2 16:11:34 2002 +++ ./dev/wi/wi_hostap.c Thu Apr 17 22:35:59 2003 @@ -1054,7 +1054,8 @@ struct ifnet *ifp = &sc->arpcom.ac_if; struct wihap_info *whi = &sc->wi_hostap_info; struct wihap_sta_info *sta; - int mcast, s; + int mcast, s, error; + ALTQ_DECL(struct altq_pktattr pktattr;) /* TODS flag must be set. */ if (!(rxfrm->wi_frame_ctl & htole16(WI_FCTL_TODS))) { @@ -1113,7 +1114,7 @@ /* Queue up for repeating. */ - IF_HANDOFF(&ifp->if_snd, m, ifp); + IFQ_HANDOFF(ifp, m, &pktattr, error); return (!mcast); } diff -urN ../sys/dev/xe/if_xe.c ./dev/xe/if_xe.c --- ../sys/dev/xe/if_xe.c Thu Feb 6 07:03:57 2003 +++ ./dev/xe/if_xe.c Thu Apr 17 22:35:59 2003 @@ -530,7 +530,8 @@ scp->ifp->if_ioctl = xe_ioctl; scp->ifp->if_watchdog = xe_watchdog; scp->ifp->if_init = xe_init; - scp->ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&scp->ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&scp->ifp->if_snd); } /* Initialise the ifmedia structure */ @@ -684,7 +685,7 @@ * Loop while there are packets to be sent, and space to send them. */ while (1) { - IF_DEQUEUE(&ifp->if_snd, mbp); /* Suck a packet off the send queue */ + IFQ_POLL(&ifp->if_snd, mbp); if (mbp == NULL) { /* @@ -699,10 +700,11 @@ } if (xe_pio_write_packet(scp, mbp) != 0) { - IF_PREPEND(&ifp->if_snd, mbp); /* Push the packet back onto the queue */ ifp->if_flags |= IFF_OACTIVE; return; } + + IFQ_DEQUEUE(&ifp->if_snd, mbp); /* Tap off here if there is a bpf listener */ if (ifp->if_bpf) { diff -urN ../sys/i386/conf/ALTQ ./i386/conf/ALTQ --- ../sys/i386/conf/ALTQ Thu Jan 1 09:00:00 1970 +++ ./i386/conf/ALTQ Fri Apr 18 00:00:42 2003 @@ -0,0 +1,293 @@ +# +# GENERIC -- Generic kernel configuration file for FreeBSD/i386 +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ./LINT configuration file. If you are +# in doubt as to the purpose or necessity of a line, check first in LINT. +# +# $FreeBSD: src/sys/i386/conf/GENERIC,v 1.246.2.51.2.2 2003/03/25 23:35:15 jhb Exp $ + +machine i386 +cpu I386_CPU +cpu I486_CPU +cpu I586_CPU +cpu I686_CPU +ident ALTQ +maxusers 0 + +#makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options MATH_EMULATE #Support for x87 emulation +options INET #InterNETworking +options INET6 #IPv6 communications protocols +options FFS #Berkeley Fast Filesystem +options FFS_ROOT #FFS usable as root device [keep this!] +options SOFTUPDATES #Enable FFS soft updates support +options UFS_DIRHASH #Improve performance on big directories +options MFS #Memory Filesystem +options MD_ROOT #MD is a potential root device +options NFS #Network Filesystem +options NFS_ROOT #NFS usable as root device, NFS required +options MSDOSFS #MSDOS Filesystem +options CD9660 #ISO 9660 Filesystem +options CD9660_ROOT #CD-ROM usable as root, CD9660 required +options PROCFS #Process filesystem +options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!] +options SCSI_DELAY=15000 #Delay (in ms) before probing SCSI +options UCONSOLE #Allow users to grab the console +options USERCONFIG #boot -c editor +options VISUAL_USERCONFIG #visual boot -c editor +options KTRACE #ktrace(1) support +options SYSVSHM #SYSV-style shared memory +options SYSVMSG #SYSV-style message queues +options SYSVSEM #SYSV-style semaphores +options P1003_1B #Posix P1003_1B real-time extensions +options _KPOSIX_PRIORITY_SCHEDULING +options ICMP_BANDLIM #Rate limit bad replies +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options AHC_REG_PRETTY_PRINT # Print register bitfields in debug + # output. Adds ~128k to driver. +options AHD_REG_PRETTY_PRINT # Print register bitfields in debug + # output. Adds ~215k to driver. + +# To make an SMP kernel, the next two are needed +#options SMP # Symmetric MultiProcessor Kernel +#options APIC_IO # Symmetric (APIC) I/O + +# To support HyperThreading, HTT is needed in addition to SMP and APIC_IO +#options HTT # HyperThreading Technology + +device isa +device eisa +device pci + +# Floppy drives +device fdc0 at isa? port IO_FD1 irq 6 drq 2 +device fd0 at fdc0 drive 0 +device fd1 at fdc0 drive 1 +# +# If you have a Toshiba Libretto with its Y-E Data PCMCIA floppy, +# don't use the above line for fdc0 but the following one: +#device fdc0 + +# ATA and ATAPI devices +device ata0 at isa? port IO_WD1 irq 14 +device ata1 at isa? port IO_WD2 irq 15 +device ata +device atadisk # ATA disk drives +device atapicd # ATAPI CDROM drives +device atapifd # ATAPI floppy drives +device atapist # ATAPI tape drives +options ATA_STATIC_ID #Static device numbering + +# SCSI Controllers +device ahb # EISA AHA1742 family +device ahc # AHA2940 and onboard AIC7xxx devices +device ahd # AHA39320/29320 and onboard AIC79xx devices +device amd # AMD 53C974 (Tekram DC-390(T)) +device isp # Qlogic family +device mpt # LSI-Logic MPT/Fusion +device ncr # NCR/Symbios Logic +device sym # NCR/Symbios Logic (newer chipsets) +options SYM_SETUP_LP_PROBE_MAP=0x40 + # Allow ncr to attach legacy NCR devices when + # both sym and ncr are configured + +device adv0 at isa? +device adw +device bt0 at isa? +device aha0 at isa? +device aic0 at isa? + +device ncv # NCR 53C500 +device nsp # Workbit Ninja SCSI-3 +device stg # TMC 18C30/18C50 + +# SCSI peripherals +device scbus # SCSI bus (required) +device da # Direct Access (disks) +device sa # Sequential Access (tape etc) +device cd # CD +device pass # Passthrough device (direct SCSI access) + +# RAID controllers interfaced to the SCSI subsystem +device asr # DPT SmartRAID V, VI and Adaptec SCSI RAID +device dpt # DPT Smartcache - See LINT for options! +device iir # Intel Integrated RAID +device mly # Mylex AcceleRAID/eXtremeRAID +device ciss # Compaq SmartRAID 5* series + +# RAID controllers +device aac # Adaptec FSA RAID, Dell PERC2/PERC3 +#device aacp # SCSI passthrough for aac (requires CAM) +device ida # Compaq Smart RAID +device amr # AMI MegaRAID +device mlx # Mylex DAC960 family +device twe # 3ware Escalade + +# atkbdc0 controls both the keyboard and the PS/2 mouse +device atkbdc0 at isa? port IO_KBD +device atkbd0 at atkbdc? irq 1 flags 0x1 +device psm0 at atkbdc? irq 12 + +device vga0 at isa? + +# splash screen/screen saver +pseudo-device splash + +# syscons is the default console driver, resembling an SCO console +device sc0 at isa? flags 0x100 + +# Enable this and PCVT_FREEBSD for pcvt vt220 compatible console driver +#device vt0 at isa? +#options XSERVER # support for X server on a vt console +#options FAT_CURSOR # start with block cursor +# If you have a ThinkPAD, uncomment this along with the rest of the PCVT lines +#options PCVT_SCANSET=2 # IBM keyboards are non-std + +device agp # support several AGP chipsets + +# Floating point support - do not disable. +device npx0 at nexus? port IO_NPX irq 13 + +# Power management support (see LINT for more options) +device apm0 at nexus? disable flags 0x20 # Advanced Power Management + +# PCCARD (PCMCIA) support +device card +device pcic0 at isa? irq 0 port 0x3e0 iomem 0xd0000 +device pcic1 at isa? irq 0 port 0x3e2 iomem 0xd4000 disable + +# Serial (COM) ports +device sio0 at isa? port IO_COM1 flags 0x10 irq 4 +device sio1 at isa? port IO_COM2 irq 3 +device sio2 at isa? disable port IO_COM3 irq 5 +device sio3 at isa? disable port IO_COM4 irq 9 + +# Parallel port +device ppc0 at isa? irq 7 +device ppbus # Parallel port bus (required) +device lpt # Printer +device plip # TCP/IP over parallel +device ppi # Parallel port interface device +#device vpo # Requires scbus and da + + +# PCI Ethernet NICs. +device de # DEC/Intel DC21x4x (``Tulip'') +device em # Intel PRO/1000 adapter Gigabit Ethernet Card (``Wiseman'') +device txp # 3Com 3cR990 (``Typhoon'') +device vx # 3Com 3c590, 3c595 (``Vortex'') + +# PCI Ethernet NICs that use the common MII bus controller code. +# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs! +device miibus # MII bus support +device dc # DEC/Intel 21143 and various workalikes +device fxp # Intel EtherExpress PRO/100B (82557, 82558) +device pcn # AMD Am79C97x PCI 10/100 NICs +device rl # RealTek 8129/8139 +device sf # Adaptec AIC-6915 (``Starfire'') +device sis # Silicon Integrated Systems SiS 900/SiS 7016 +device ste # Sundance ST201 (D-Link DFE-550TX) +device tl # Texas Instruments ThunderLAN +device tx # SMC EtherPower II (83c170 ``EPIC'') +device vr # VIA Rhine, Rhine II +device wb # Winbond W89C840F +device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') +device bge # Broadcom BCM570x (``Tigon III'') + +# ISA Ethernet NICs. +# 'device ed' requires 'device miibus' +device ed0 at isa? disable port 0x280 irq 10 iomem 0xd8000 +device ex +device ep +device fe0 at isa? disable port 0x300 +# Xircom Ethernet +device xe +# PRISM I IEEE 802.11b wireless NIC. +device awi +# WaveLAN/IEEE 802.11 wireless NICs. Note: the WaveLAN/IEEE really +# exists only as a PCMCIA device, so there is no ISA attachment needed +# and resources will always be dynamically assigned by the pccard code. +device wi +# Aironet 4500/4800 802.11 wireless NICs. Note: the declaration below will +# work for PCMCIA and PCI cards, as well as ISA cards set to ISA PnP +# mode (the factory default). If you set the switches on your ISA +# card for a manually chosen I/O address and IRQ, you must specify +# those parameters here. +device an +# The probe order of these is presently determined by i386/isa/isa_compat.c. +device ie0 at isa? disable port 0x300 irq 10 iomem 0xd0000 +#device le0 at isa? disable port 0x300 irq 5 iomem 0xd0000 +device lnc0 at isa? disable port 0x280 irq 10 drq 0 +device cs0 at isa? disable port 0x300 +device sn0 at isa? disable port 0x300 irq 10 + +# Pseudo devices - the number indicates how many units to allocate. +pseudo-device loop # Network loopback +pseudo-device ether # Ethernet support +pseudo-device sl 1 # Kernel SLIP +pseudo-device ppp 1 # Kernel PPP +pseudo-device tun # Packet tunnel. +pseudo-device pty # Pseudo-ttys (telnet etc) +pseudo-device md # Memory "disks" +pseudo-device gif # IPv6 and IPv4 tunneling +pseudo-device faith 1 # IPv6-to-IPv4 relaying (translation) + +# The `bpf' pseudo-device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +pseudo-device bpf #Berkeley packet filter + +# USB support +device uhci # UHCI PCI->USB interface +device ohci # OHCI PCI->USB interface +device usb # USB Bus (required) +device ugen # Generic +device uhid # "Human Interface Devices" +device ukbd # Keyboard +device ulpt # Printer +device umass # Disks/Mass storage - Requires scbus and da +device ums # Mouse +device uscanner # Scanners +device urio # Diamond Rio MP3 Player +# USB Ethernet, requires mii +device aue # ADMtek USB ethernet +device cue # CATC USB ethernet +device kue # Kawasaki LSI USB ethernet + +# ALTQ options +options ALTQ #alternate queueing +#options ALTQ_CBQ #class based queueing +#options ALTQ_WFQ #weighted fair queueing +#options ALTQ_FIFOQ #fifo queueing +#options ALTQ_RED #random early detection +#options ALTQ_FLOWVALVE #flowvalve for RED (needs RED) +#options ALTQ_RIO #triple red for diffserv (needs RED) +#options ALTQ_LOCALQ #local use +#options ALTQ_HFSC #hierarchical fair service curve +#options ALTQ_JOBS #joint buffer management and scheduling +#options ALTQ_IPSEC #check ipsec in IPv4 +#options ALTQ_CDNR #diffserv traffic conditioner +#options ALTQ_BLUE #blue by wu-chang feng +#options ALTQ_PRIQ #priority queue +#options ALTQ_NOPCC #don't use processor cycle counter +#options ALTQ_DEBUG #for debugging +# you might want to set kernel timer to 1kHz if you use CBQ, +# especially with 100baseT +#options HZ=1000 + +# options added for ALTQ +#options MROUTING # Multicast routing +#pseudo-device atm +#device en +#options NATM #native mode atm diff -urN ../sys/i386/conf/LINT ./i386/conf/LINT --- ../sys/i386/conf/LINT Sat Mar 29 05:05:39 2003 +++ ./i386/conf/LINT Thu Apr 17 22:35:59 2003 @@ -2720,6 +2720,23 @@ # An embedded system might want to run something other than init. options INIT_PATH="/sbin/init:/stand/sysinstall" +# ALTQ options +options ALTQ #alternate queueing +options ALTQ_CBQ #class based queueing +options ALTQ_WFQ #weighted fair queueing +options ALTQ_FIFOQ #fifo queueing +options ALTQ_RED #random early detection +options ALTQ_FLOWVALVE #flowvalve for RED (needs RED) +options ALTQ_RIO #triple red for diffserv (needs RED) +options ALTQ_LOCALQ #local use +options ALTQ_HFSC #hierarchical fair service curve +options ALTQ_JOBS #joint buffer management and scheduling +options ALTQ_IPSEC #check ipsec in IPv4 +options ALTQ_CDNR #diffserv traffic conditioner +options ALTQ_BLUE #blue by wu-chang feng +options ALTQ_PRIQ #priority queue +options ALTQ_NOPCC #don't use processor cycle counter +options ALTQ_DEBUG #for debugging # Debug options options BUS_DEBUG # enable newbus debugging options DEBUG_VFS_LOCKS # enable vfs lock debugging diff -urN ../sys/i386/isa/if_cx.c ./i386/isa/if_cx.c --- ../sys/i386/isa/if_cx.c Thu Nov 18 17:36:42 1999 +++ ./i386/isa/if_cx.c Thu Apr 17 22:35:59 2003 @@ -273,6 +273,7 @@ c->ifp->if_ioctl = cxsioctl; c->ifp->if_start = (start_func_t) cxstart; c->ifp->if_watchdog = (watchdog_func_t) cxwatchdog; + IFQ_SET_READY(&c->ifp->if_snd); /* Init routine is never called by upper level? */ sppp_attach (c->ifp); if_attach (c->ifp); diff -urN ../sys/i386/isa/if_lnc.c ./i386/isa/if_lnc.c --- ../sys/i386/isa/if_lnc.c Wed Feb 13 09:43:10 2002 +++ ./i386/isa/if_lnc.c Thu Apr 17 22:35:59 2003 @@ -356,6 +356,7 @@ head = desc->buff.mbuf; head->m_flags |= M_PKTHDR; + bzero(&head->m_pkthdr, sizeof(head->m_pkthdr)); m = head; do { @@ -1240,7 +1241,8 @@ sc->arpcom.ac_if.if_type = IFT_ETHER; sc->arpcom.ac_if.if_addrlen = ETHER_ADDR_LEN; sc->arpcom.ac_if.if_hdrlen = ETHER_HDR_LEN; - sc->arpcom.ac_if.if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&sc->arpcom.ac_if.if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&sc->arpcom.ac_if.if_snd); ether_ifattach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED); @@ -1649,7 +1651,7 @@ do { - IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, head); + IFQ_DEQUEUE(&sc->arpcom.ac_if.if_snd, head); if (!head) return; diff -urN ../sys/i386/isa/if_wl.c ./i386/isa/if_wl.c --- ../sys/i386/isa/if_wl.c Tue Jul 18 06:24:32 2000 +++ ./i386/isa/if_wl.c Thu Apr 17 22:35:59 2003 @@ -505,6 +505,7 @@ ifp->if_done ifp->if_reset */ + IFQ_SET_READY(&ifp->if_snd); ether_ifattach(ifp, ETHER_BPF_SUPPORTED); bcopy(&sc->wl_addr[0], sc->wl_ac.ac_enaddr, WAVELAN_ADDR_SIZE); @@ -886,7 +887,7 @@ /* get ourselves some data */ ifp = &(sc->wl_if); - IF_DEQUEUE(&ifp->if_snd, m); + IFQ_DEQUEUE(&ifp->if_snd, m); if (m != (struct mbuf *)0) { /* let BPF see it before we commit it */ if (ifp->if_bpf) { diff -urN ../sys/modules/Makefile ./modules/Makefile --- ../sys/modules/Makefile Sat Mar 1 00:57:18 2003 +++ ./modules/Makefile Thu Apr 17 23:40:23 2003 @@ -132,6 +132,8 @@ wi \ xe +SUBDIR+=altq + .if ${MACHINE} == "i386" SUBDIR+=aac \ asr \ diff -urN ../sys/modules/altq/Makefile ./modules/altq/Makefile --- ../sys/modules/altq/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/Makefile Thu Apr 17 22:35:59 2003 @@ -0,0 +1,4 @@ + +SUBDIR= altq_blue altq_cbq altq_cdnr altq_fifoq altq_hfsc altq_jobs altq_localq altq_priq altq_red altq_rio altq_wfq + +.include diff -urN ../sys/modules/altq/Makefile.inc ./modules/altq/Makefile.inc --- ../sys/modules/altq/Makefile.inc Thu Jan 1 09:00:00 1970 +++ ./modules/altq/Makefile.inc Thu Apr 17 22:35:59 2003 @@ -0,0 +1,3 @@ +# $Id: altq-3.1-sys-altq-freebsd-4.8.patch,v 1.1.1.1 2006/09/28 03:00:42 kjc Exp $ + +KLDMOD= true diff -urN ../sys/modules/altq/altq_blue/Makefile ./modules/altq/altq_blue/Makefile --- ../sys/modules/altq/altq_blue/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_blue/Makefile Thu Apr 17 22:35:59 2003 @@ -0,0 +1,28 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_blue +SRCS= altq_blue.c opt_altq.h opt_inet.h opt_inet6.h + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h opt_inet.h opt_inet6.h + +ALTQMOD_INET?= 1 +ALTQMOD_INET6?= 1 + +opt_altq.h: + echo "#define ALTQ_BLUE 1" > opt_altq.h + +opt_inet.h: + touch opt_inet.h +.if ${ALTQMOD_INET} > 0 + echo "#define INET 1" > opt_inet.h +.endif + +opt_inet6.h: + touch opt_inet6.h +.if ${ALTQMOD_INET6} > 0 + echo "#define INET6 1" > opt_inet6.h +.endif + +.include + diff -urN ../sys/modules/altq/altq_cbq/Makefile ./modules/altq/altq_cbq/Makefile --- ../sys/modules/altq/altq_cbq/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_cbq/Makefile Thu Apr 17 22:35:59 2003 @@ -0,0 +1,41 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_cbq +SRCS= altq_cbq.c altq_rmclass.c opt_altq.h opt_inet.h opt_inet6.h +KMODDEPS= altq_red altq_rio + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h opt_inet.h opt_inet6.h + +ALTQMOD_ALTQ_RED?= 1 +ALTQMOD_ALTQ_RIO?= 1 +ALTQMOD_ALTQ_FLOWVALVE?= 1 +ALTQMOD_INET?= 1 +ALTQMOD_INET6?= 1 + +opt_altq.h: + echo "#define ALTQ_CBQ 1" > opt_altq.h +.if ${ALTQMOD_ALTQ_RED} > 0 + echo "#define ALTQ_RED 1" >> opt_altq.h +.endif +.if ${ALTQMOD_ALTQ_RIO} > 0 + echo "#define ALTQ_RIO 1" >> opt_altq.h +.endif +.if ${ALTQMOD_ALTQ_FLOWVALVE} > 0 + echo "#define ALTQ_FLOWVALVE 1" >> opt_altq.h +.endif + +opt_inet.h: + touch opt_inet.h +.if ${ALTQMOD_INET} > 0 + echo "#define INET 1" > opt_inet.h +.endif + +opt_inet6.h: + touch opt_inet6.h +.if ${ALTQMOD_INET6} > 0 + echo "#define INET6 1" > opt_inet6.h +.endif + +.include + diff -urN ../sys/modules/altq/altq_cdnr/Makefile ./modules/altq/altq_cdnr/Makefile --- ../sys/modules/altq/altq_cdnr/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_cdnr/Makefile Thu Apr 17 22:35:59 2003 @@ -0,0 +1,28 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_cdnr +SRCS= altq_cdnr.c opt_altq.h opt_inet.h opt_inet6.h + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h opt_inet.h opt_inet6.h + +ALTQMOD_INET?= 1 +ALTQMOD_INET6?= 1 + +opt_altq.h: + echo "#define ALTQ_CDNR 1" > opt_altq.h + +opt_inet.h: + touch opt_inet.h +.if ${ALTQMOD_INET} > 0 + echo "#define INET 1" > opt_inet.h +.endif + +opt_inet6.h: + touch opt_inet6.h +.if ${ALTQMOD_INET6} > 0 + echo "#define INET6 1" > opt_inet6.h +.endif + +.include + diff -urN ../sys/modules/altq/altq_fifoq/Makefile ./modules/altq/altq_fifoq/Makefile --- ../sys/modules/altq/altq_fifoq/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_fifoq/Makefile Thu Apr 17 22:36:00 2003 @@ -0,0 +1,13 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_fifoq +SRCS= altq_fifoq.c opt_altq.h + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h + +opt_altq.h: + echo "#define ALTQ_FIFOQ 1" > opt_altq.h + +.include + diff -urN ../sys/modules/altq/altq_hfsc/Makefile ./modules/altq/altq_hfsc/Makefile --- ../sys/modules/altq/altq_hfsc/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_hfsc/Makefile Thu Apr 17 22:36:00 2003 @@ -0,0 +1,40 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_hfsc +SRCS= altq_hfsc.c opt_altq.h opt_inet.h opt_inet6.h +KMODDEPS= altq_red altq_rio + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h opt_inet.h opt_inet6.h + +ALTQMOD_ALTQ_RED?= 1 +ALTQMOD_ALTQ_RIO?= 1 +ALTQMOD_ALTQ_FLOWVALVE?= 1 +ALTQMOD_INET?= 1 +ALTQMOD_INET6?= 1 + +opt_altq.h: + echo "#define ALTQ_HFSC 1" > opt_altq.h +.if ${ALTQMOD_ALTQ_RED} > 0 + echo "#define ALTQ_RED 1" >> opt_altq.h +.endif +.if ${ALTQMOD_ALTQ_RIO} > 0 + echo "#define ALTQ_RIO 1" >> opt_altq.h +.endif +.if ${ALTQMOD_ALTQ_FLOWVALVE} > 0 + echo "#define ALTQ_FLOWVALVE 1" >> opt_altq.h +.endif + +opt_inet.h: + touch opt_inet.h +.if ${ALTQMOD_INET} > 0 + echo "#define INET 1" > opt_inet.h +.endif + +opt_inet6.h: + touch opt_inet6.h +.if ${ALTQMOD_INET6} > 0 + echo "#define INET6 1" > opt_inet6.h +.endif + +.include diff -urN ../sys/modules/altq/altq_jobs/Makefile ./modules/altq/altq_jobs/Makefile --- ../sys/modules/altq/altq_jobs/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_jobs/Makefile Thu Apr 17 22:36:00 2003 @@ -0,0 +1,27 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_jobs +SRCS= altq_jobs.c opt_altq.h opt_inet.h opt_inet6.h + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h opt_inet.h opt_inet6.h + +ALTQMOD_INET?= 1 +ALTQMOD_INET6?= 1 + +opt_altq.h: + echo "#define ALTQ_JOBS 1" > opt_altq.h + +opt_inet.h: + touch opt_inet.h +.if ${ALTQMOD_INET} > 0 + echo "#define INET 1" > opt_inet.h +.endif + +opt_inet6.h: + touch opt_inet6.h +.if ${ALTQMOD_INET6} > 0 + echo "#define INET6 1" > opt_inet6.h +.endif + +.include diff -urN ../sys/modules/altq/altq_localq/Makefile ./modules/altq/altq_localq/Makefile --- ../sys/modules/altq/altq_localq/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_localq/Makefile Thu Apr 17 22:36:00 2003 @@ -0,0 +1,12 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_localq +SRCS= altq_localq.c opt_altq.h + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h + +opt_altq.h: + echo "#define ALTQ_LOCALQ 1" > opt_altq.h + +.include diff -urN ../sys/modules/altq/altq_priq/Makefile ./modules/altq/altq_priq/Makefile --- ../sys/modules/altq/altq_priq/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_priq/Makefile Thu Apr 17 22:36:00 2003 @@ -0,0 +1,40 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_priq +SRCS= altq_priq.c opt_altq.h opt_inet.h opt_inet6.h +KMODDEPS= altq_red altq_rio + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h opt_inet.h opt_inet6.h + +ALTQMOD_ALTQ_RED?= 1 +ALTQMOD_ALTQ_RIO?= 1 +ALTQMOD_ALTQ_FLOWVALVE?= 1 +ALTQMOD_INET?= 1 +ALTQMOD_INET6?= 1 + +opt_altq.h: + echo "#define ALTQ_PRIQ 1" > opt_altq.h +.if ${ALTQMOD_ALTQ_RED} > 0 + echo "#define ALTQ_RED 1" >> opt_altq.h +.endif +.if ${ALTQMOD_ALTQ_RIO} > 0 + echo "#define ALTQ_RIO 1" >> opt_altq.h +.endif +.if ${ALTQMOD_ALTQ_FLOWVALVE} > 0 + echo "#define ALTQ_FLOWVALVE 1" >> opt_altq.h +.endif + +opt_inet.h: + touch opt_inet.h +.if ${ALTQMOD_INET} > 0 + echo "#define INET 1" > opt_inet.h +.endif + +opt_inet6.h: + touch opt_inet6.h +.if ${ALTQMOD_INET6} > 0 + echo "#define INET6 1" > opt_inet6.h +.endif + +.include diff -urN ../sys/modules/altq/altq_red/Makefile ./modules/altq/altq_red/Makefile --- ../sys/modules/altq/altq_red/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_red/Makefile Thu Apr 17 22:36:00 2003 @@ -0,0 +1,32 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_red +SRCS= altq_red.c opt_altq.h opt_inet.h opt_inet6.h + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h opt_inet.h opt_inet6.h + +ALTQMOD_ALTQ_FLOWVALVE?= 1 +ALTQMOD_INET?= 1 +ALTQMOD_INET6?= 1 + +opt_altq.h: + echo "#define ALTQ_RED 1" > opt_altq.h +.if ${ALTQMOD_ALTQ_FLOWVALVE} > 0 + echo "#define ALTQ_FLOWVALVE 1" >> opt_altq.h +.endif + +opt_inet.h: + touch opt_inet.h +.if ${ALTQMOD_INET} > 0 + echo "#define INET 1" > opt_inet.h +.endif + +opt_inet6.h: + touch opt_inet6.h +.if ${ALTQMOD_INET6} > 0 + echo "#define INET6 1" > opt_inet6.h +.endif + +.include + diff -urN ../sys/modules/altq/altq_rio/Makefile ./modules/altq/altq_rio/Makefile --- ../sys/modules/altq/altq_rio/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_rio/Makefile Thu Apr 17 22:36:00 2003 @@ -0,0 +1,28 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_rio +SRCS= altq_rio.c opt_altq.h opt_inet.h opt_inet6.h + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h opt_inet.h opt_inet6.h + +ALTQMOD_INET?= 1 +ALTQMOD_INET6?= 1 + +opt_altq.h: + echo "#define ALTQ_RIO 1" > opt_altq.h + +opt_inet.h: + touch opt_inet.h +.if ${ALTQMOD_INET} > 0 + echo "#define INET 1" > opt_inet.h +.endif + +opt_inet6.h: + touch opt_inet6.h +.if ${ALTQMOD_INET6} > 0 + echo "#define INET6 1" > opt_inet6.h +.endif + +.include + diff -urN ../sys/modules/altq/altq_wfq/Makefile ./modules/altq/altq_wfq/Makefile --- ../sys/modules/altq/altq_wfq/Makefile Thu Jan 1 09:00:00 1970 +++ ./modules/altq/altq_wfq/Makefile Thu Apr 17 22:36:00 2003 @@ -0,0 +1,26 @@ + +.PATH: ${.CURDIR}/../../../altq +KMOD= altq_wfq +SRCS= altq_wfq.c opt_altq.h opt_inet.h opt_inet6.h + +CFLAGS+= -DALTQ +CLEANFILES+= opt_altq.h opt_inet.h opt_inet6.h + +ALTQMOD_INET?= 1 +ALTQMOD_INET6?= 1 + +opt_altq.h: + echo "#define ALTQ_WFQ 1" > opt_altq.h + +opt_inet.h: + touch opt_inet.h +.if ${ALTQMOD_INET} > 0 + echo "#define INET 1" > opt_inet.h +.endif + +opt_inet6.h: + touch opt_inet6.h +.if ${ALTQMOD_INET6} > 0 + echo "#define INET6 1" > opt_inet6.h +.endif +.include diff -urN ../sys/net/bridge.c ./net/bridge.c --- ../sys/net/bridge.c Fri Jan 24 06:06:44 2003 +++ ./net/bridge.c Thu Apr 17 23:45:30 2003 @@ -100,6 +100,9 @@ #include #include #include +#ifdef ALTQ +#include +#endif #include /* for struct arpcom */ #include @@ -802,6 +805,7 @@ int once = 0; /* loop only once */ struct ifnet *real_dst = dst ; /* real dst from ether_output */ struct ip_fw_args args; + int error = 0; /* * XXX eh is usually a pointer within the mbuf (some ethernet drivers @@ -994,6 +998,11 @@ for (;;) { if (last) { /* need to forward packet leftover from previous loop */ struct mbuf *m ; +#ifdef ALTQ + struct altq_pktattr pktattr; + int af; +#endif + if (shared == 0 && once ) { /* no need to copy */ m = m0 ; m0 = NULL ; /* original is gone */ @@ -1004,6 +1013,26 @@ return m0 ; /* the original is still there... */ } } +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&last->if_snd)) { + u_short ether_type; + + /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + ether_type = ntohs(eh->ether_type); + if (ether_type == ETHERTYPE_IP) + af = AF_INET; +#ifdef INET6 + else if (ether_type == ETHERTYPE_IPV6) + af = AF_INET6; +#endif + else + af = AF_UNSPEC; + IFQ_CLASSIFY(&last->if_snd, m, af, &pktattr); + } +#endif /* ALTQ */ /* * Add header (optimized for the common case of eh pointing * already into the mbuf) and execute last part of ether_output: @@ -1022,7 +1051,8 @@ return m0; bcopy(&save_eh, mtod(m, struct ether_header *), ETHER_HDR_LEN); } - if (!IF_HANDOFF(&last->if_snd, m, last)) { + IFQ_HANDOFF(last, m, &pktattr, error); + if (error != 0) { #if 0 BDG_MUTE(last); /* should I also mute ? */ #endif @@ -1039,7 +1069,10 @@ * up and running, is not the source interface, and belongs to * the same cluster as the 'real_dst', then send here. */ - if ( BDG_USED(ifp) && !BDG_MUTED(ifp) && !_IF_QFULL(&ifp->if_snd) && + if ( BDG_USED(ifp) && !BDG_MUTED(ifp) && +#ifndef ALTQ + !_IF_QFULL(&ifp->if_snd) && +#endif (ifp->if_flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING) && ifp != src && BDG_SAMECLUSTER(ifp, real_dst) ) last = ifp ; diff -urN ../sys/net/if.c ./net/if.c --- ../sys/net/if.c Tue Jan 28 20:19:05 2003 +++ ./net/if.c Thu Apr 17 22:36:00 2003 @@ -77,7 +77,11 @@ static int ifconf __P((u_long, caddr_t)); static void ifinit __P((void *)); +#ifdef ALTQ +static void if_qflush __P((struct ifaltq *)); +#else static void if_qflush __P((struct ifqueue *)); +#endif static void if_slowtimo __P((void *)); static void link_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *)); static int if_rtdel __P((struct radix_node *, void *)); @@ -227,6 +231,14 @@ TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link); } +#ifdef ALTQ + ifp->if_snd.altq_type = 0; + ifp->if_snd.altq_disc = NULL; + ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE; + ifp->if_snd.altq_tbr = NULL; + ifp->if_snd.altq_ifp = ifp; +#endif + /* Announce the interface. */ rt_ifannouncemsg(ifp, IFAN_ARRIVAL); } @@ -249,6 +261,12 @@ */ s = splnet(); if_down(ifp); +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&ifp->if_snd)) + altq_disable(&ifp->if_snd); + if (ALTQ_IS_ATTACHED(&ifp->if_snd)) + altq_detach(&ifp->if_snd); +#endif /* * Remove address from ifnet_addrs[] and maybe decrement if_index. @@ -823,10 +841,18 @@ */ static void if_qflush(ifq) +#ifdef ALTQ + struct ifaltq *ifq; +#else register struct ifqueue *ifq; +#endif { register struct mbuf *m, *n; +#ifdef ALTQ + if (ALTQ_IS_ENABLED(ifq)) + ALTQ_PURGE(ifq); +#endif n = ifq->ifq_head; while ((m = n) != 0) { n = m->m_act; diff -urN ../sys/net/if_atm.h ./net/if_atm.h --- ../sys/net/if_atm.h Wed Dec 29 13:38:34 1999 +++ ./net/if_atm.h Thu Apr 17 22:36:00 2003 @@ -37,6 +37,14 @@ * net/if_atm.h */ +#ifndef NO_ATM_PVCEXT +/* + * ATM_PVCEXT enables PVC extention: VP/VC shaping + * and PVC shadow interfaces. + */ +#define ATM_PVCEXT /* enable pvc extention */ +#endif + #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) #define RTALLOC1(A,B) rtalloc1((A),(B)) #elif defined(__FreeBSD__) @@ -61,6 +69,9 @@ #define ATM_PH_AAL5 0x01 /* use AAL5? (0 == aal0) */ #define ATM_PH_LLCSNAP 0x02 /* use the LLC SNAP encoding (iff aal5) */ +#ifdef ATM_PVCEXT +#define ATM_PH_INERNAL 0x20 /* reserve for kernel internal use */ +#endif #define ATM_PH_DRIVER7 0x40 /* reserve for driver's use */ #define ATM_PH_DRIVER8 0x80 /* reserve for driver's use */ @@ -79,6 +90,35 @@ #define SIOCATMENA _IOWR('a', 123, struct atm_pseudoioctl) /* enable */ #define SIOCATMDIS _IOWR('a', 124, struct atm_pseudoioctl) /* disable */ +#ifdef ATM_PVCEXT + +/* structure to control PVC transmitter */ +struct pvctxreq { + /* first entry must be compatible with struct ifreq */ + char pvc_ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ + struct atm_pseudohdr pvc_aph; /* (flags) + vpi:vci */ + struct atm_pseudohdr pvc_joint; /* for vp shaping: another vc + to share the shaper */ + int pvc_pcr; /* peak cell rate (shaper value) */ +}; + +/* structure to control PVC bridging */ +struct pvcfwdreq { + /* first entry must be compatible with struct ifreq */ + char pvc_ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ + char pvc_ifname2[IFNAMSIZ]; /* if name to be bridged to/from */ + int pvc_op; /* 1:add 0:delete */ +}; + +/* use ifioctl for now */ +#define SIOCSPVCFWD _IOW('i', 93, struct pvcfwdreq) +#define SIOCGPVCFWD _IOWR('i', 94, struct pvcfwdreq) +#define SIOCSPVCTX _IOWR('i', 95, struct pvctxreq) +#define SIOCGPVCTX _IOWR('i', 96, struct pvctxreq) +#define SIOCSPVCSIF _IOWR('i', 97, struct ifreq) +#define SIOCGPVCSIF _IOWR('i', 98, struct ifreq) + +#endif /* ATM_PVCEXT */ /* * XXX forget all the garbage in if_llc.h and do it the easy way @@ -105,3 +145,28 @@ struct rtentry *)); #endif +#ifdef ATM_PVCEXT +#ifdef _KERNEL +#include +/* + * ATM PVC subinterface: a trick to assign a subinterface + * to a PVC. + * with a pvc subinterface, each PVC looks like an individual + * Point-to-Point interface. + * as opposed to the NBMA model, a pvc subinterface is inherently + * multicast capable (no LANE/MARS required). + */ +struct pvcsif { + /* + * The ifnet struct _must_ be at the head of this structure. + */ + struct ifnet sif_if; /* ifnet structure per pvc */ + struct atm_pseudohdr sif_aph; /* flags + vpi:vci */ + int sif_vci; /* vci no */ + struct ifnet *sif_fwdifp; /* bridging ifp */ + LIST_ENTRY(pvcsif) sif_links; +}; +struct ifnet *pvcsif_alloc __P((void)); +int pvc_set_fwd __P((char *, char *, int)); +#endif +#endif /* ATM_PVCEXT */ diff -urN ../sys/net/if_atmsubr.c ./net/if_atmsubr.c --- ../sys/net/if_atmsubr.c Tue Mar 6 09:29:26 2001 +++ ./net/if_atmsubr.c Thu Apr 17 22:36:00 2003 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -95,18 +96,26 @@ struct rtentry *rt0; { u_int16_t etype = 0; /* if using LLC/SNAP */ - int s, error = 0, sz; + int s, error = 0, sz, len; struct atm_pseudohdr atmdst, *ad; struct mbuf *m = m0; struct rtentry *rt; struct atmllc *atmllc; struct atmllc *llc_hdr = NULL; u_int32_t atm_flags; + ALTQ_DECL(struct altq_pktattr pktattr;) if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) senderr(ENETDOWN); /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, + (dst != NULL ? dst->sa_family : AF_UNSPEC), &pktattr); + + /* * check route */ if ((rt = rt0) != NULL) { @@ -139,12 +148,24 @@ if (dst) { switch (dst->sa_family) { #if defined(INET) || defined(INET6) +#ifdef INET case AF_INET: +#endif +#ifdef INET6 case AF_INET6: +#endif if (dst->sa_family == AF_INET6) etype = htons(ETHERTYPE_IPV6); else etype = htons(ETHERTYPE_IP); +#ifdef ATM_PVCEXT + if (ifp->if_flags & IFF_POINTOPOINT) { + /* pvc subinterface */ + struct pvcsif *pvcsif = (struct pvcsif *)ifp; + atmdst = pvcsif->sif_aph; + break; + } +#endif if (!atmresolve(rt, m, dst, &atmdst)) { m = NULL; /* XXX: atmresolve already free'd it */ @@ -203,14 +224,14 @@ * Queue message on interface, and start output if interface * not yet active. */ + len = m->m_pkthdr.len; s = splimp(); - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); + IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); + if (error) { splx(s); - senderr(ENOBUFS); + return (error); } - ifp->if_obytes += m->m_pkthdr.len; - IF_ENQUEUE(&ifp->if_snd, m); + ifp->if_obytes += len; if ((ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); splx(s); @@ -282,6 +303,33 @@ m_adj(m, sizeof(*alc)); } +#ifdef ATM_PVCEXT + /* atm bridging support */ + if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LINK2)) == + (IFF_POINTOPOINT|IFF_LINK2)) { + struct pvcsif *pvcsif = (struct pvcsif *)ifp; + + if (pvcsif->sif_fwdifp != NULL) { + struct sockaddr dst; + + /* set address family to dummy dst addr */ + switch (etype) { + case ETHERTYPE_IP: + dst.sa_family = AF_INET; + break; + case ETHERTYPE_IPV6: + dst.sa_family = AF_INET6; + break; + default: + m_freem(m); + return; + } + atm_output(pvcsif->sif_fwdifp, m, &dst, NULL); + return; + } + } +#endif /* ATM_PVCEXT */ + switch (etype) { #ifdef INET case ETHERTYPE_IP: @@ -325,7 +373,7 @@ ifp->if_hdrlen = 0; ifp->if_mtu = ATMMTU; ifp->if_output = atm_output; - ifp->if_snd.ifq_maxlen = 50; /* dummy */ + IFQ_SET_MAXLEN(&ifp->if_snd, 50); /* dummy */ #if defined(__NetBSD__) || defined(__OpenBSD__) for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != 0; @@ -347,3 +395,86 @@ } } + +#ifdef ATM_PVCEXT + +static int pvc_max_number = 16; /* max number of PVCs */ +static int pvc_number = 0; /* pvc unit number */ + +struct ifnet * +pvcsif_alloc() +{ + struct pvcsif *pvcsif; + + if (pvc_number >= pvc_max_number) + return (NULL); + MALLOC(pvcsif, struct pvcsif *, sizeof(struct pvcsif), + M_DEVBUF, M_WAITOK); + if (pvcsif == NULL) + return (NULL); + bzero(pvcsif, sizeof(struct pvcsif)); + +#ifdef __NetBSD__ + sprintf(pvcsif->sif_if.if_xname, "pvc%d", pvc_number++); +#else + pvcsif->sif_if.if_name = "pvc"; + pvcsif->sif_if.if_unit = pvc_number++; +#endif + return (&pvcsif->sif_if); +} + +/* + * pvc bridging support: + * add or delete brigding between 2 pvc interfaces. + */ +int +pvc_set_fwd(if_name, if_name2, op) + char *if_name, *if_name2; + int op; /* 0:delete 1:add 2:get */ +{ + struct ifnet *ifp, *ifp2; + struct pvcsif *pvcsif, *pvcsif2; + + if (strncmp(if_name, "pvc", 3) != 0 + || (ifp = ifunit(if_name)) == NULL) + return (EINVAL); + pvcsif = (struct pvcsif *)ifp; + + if (op == 2) { + /* get bridging info */ + if ((ifp2 = pvcsif->sif_fwdifp) == NULL) + *if_name2 = '\0'; + else +#ifdef __NetBSD__ + sprintf(if_name2, "%s", ifp2->if_xname); +#else + sprintf(if_name2, "%s%d", + ifp2->if_name, ifp2->if_unit); +#endif + return (0); + } + + if (strncmp(if_name2, "pvc", 3) != 0 + || (ifp2 = ifunit(if_name2)) == NULL) + return (EINVAL); + pvcsif2 = (struct pvcsif *)ifp2; + + if (op) { + /* set up bridging */ + pvcsif->sif_fwdifp = ifp2; + pvcsif2->sif_fwdifp = ifp; + ifp->if_flags |= IFF_LINK2; /* use IFF_LINK2 to show */ + ifp2->if_flags |= IFF_LINK2; /* bridging is enabled */ + } + else { + /* delete bridging */ + if (pvcsif->sif_fwdifp != ifp2 || pvcsif2->sif_fwdifp != ifp) + return (EINVAL); + pvcsif->sif_fwdifp = NULL; + pvcsif2->sif_fwdifp = NULL; + ifp->if_flags &= ~IFF_LINK2; + ifp2->if_flags &= ~IFF_LINK2; + } + return (0); +} +#endif /* ATM_PVCEXT */ diff -urN ../sys/net/if_ethersubr.c ./net/if_ethersubr.c --- ../sys/net/if_ethersubr.c Fri Dec 6 14:08:35 2002 +++ ./net/if_ethersubr.c Thu Apr 17 22:36:00 2003 @@ -382,6 +382,7 @@ int error = 0; int s; struct ip_fw *rule = NULL; + ALTQ_DECL(struct altq_pktattr pktattr;) /* Extract info from dummynet tag, ignore others */ for (; m->m_type == MT_TAG; m = m->m_next) @@ -404,6 +405,10 @@ } no_bridge: +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&ifp->if_snd)) + altq_etherclassify(&ifp->if_snd, m, &pktattr); +#endif s = splimp(); if (IPFW_LOADED && ether_ipfw != 0) { struct ether_header save_eh, *eh; @@ -436,8 +441,7 @@ * Queue message on interface, update output statistics if * successful, and start output if interface not yet active. */ - if (!IF_HANDOFF(&ifp->if_snd, m, ifp)) - error = ENOBUFS; + IFQ_HANDOFF(ifp, m, &pktattr, error); splx(s); return (error); } @@ -808,8 +812,8 @@ } break; dropanyway: - default: - if (ng_ether_input_orphan_p != NULL) + default: + if (ng_ether_input_orphan_p != NULL) (*ng_ether_input_orphan_p)(ifp, m, eh); else m_freem(m); @@ -877,6 +881,81 @@ bdgtakeifaces_ptr(); } +#ifdef ALTQ +/* + * find the size of ethernet header, and call classifier + */ +void +altq_etherclassify(ifq, m, pktattr) + struct ifaltq *ifq; + struct mbuf *m; + struct altq_pktattr *pktattr; +{ + struct ether_header *eh; + u_short ether_type; + int hlen, af, hdrsize; + caddr_t hdr; + + hlen = sizeof(struct ether_header); + eh = mtod(m, struct ether_header *); + + ether_type = ntohs(eh->ether_type); + if (ether_type < ETHERMTU) { + /* ick! LLC/SNAP */ + struct llc *llc = (struct llc *)(eh + 1); + hlen += 8; + + if (m->m_len < hlen || + llc->llc_dsap != LLC_SNAP_LSAP || + llc->llc_ssap != LLC_SNAP_LSAP || + llc->llc_control != LLC_UI) + goto bad; /* not snap! */ + + ether_type = ntohs(llc->llc_un.type_snap.ether_type); + } + + if (ether_type == ETHERTYPE_IP) { + af = AF_INET; + hdrsize = 20; /* sizeof(struct ip) */ +#ifdef INET6 + } else if (ether_type == ETHERTYPE_IPV6) { + af = AF_INET6; + hdrsize = 40; /* sizeof(struct ip6_hdr) */ +#endif + } else + goto bad; + + while (m->m_len <= hlen) { + hlen -= m->m_len; + m = m->m_next; + } + hdr = m->m_data + hlen; + if (m->m_len < hlen + hdrsize) { + /* + * ip header is not in a single mbuf. this should not + * happen in the current code. + * (todo: use m_pulldown in the future) + */ + goto bad; + } + m->m_data += hlen; + m->m_len -= hlen; + if (ALTQ_NEEDS_CLASSIFY(ifq)) + pktattr->pattr_class = + (*ifq->altq_classify)(ifq->altq_clfier, m, af); + m->m_data -= hlen; + m->m_len += hlen; + + pktattr->pattr_af = af; + pktattr->pattr_hdr = hdr; + return; + +bad: + pktattr->pattr_class = NULL; + pktattr->pattr_hdr = NULL; + pktattr->pattr_af = AF_UNSPEC; +} +#endif /* ALTQ */ SYSCTL_DECL(_net_link); SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet"); SYSCTL_INT(_net_link_ether, OID_AUTO, ipfw, CTLFLAG_RW, diff -urN ../sys/net/if_fddisubr.c ./net/if_fddisubr.c --- ../sys/net/if_fddisubr.c Thu Feb 21 08:34:09 2002 +++ ./net/if_fddisubr.c Thu Apr 17 22:36:00 2003 @@ -128,11 +128,13 @@ struct rtentry *rt0; { u_int16_t type; - int s, loop_copy = 0, error = 0, hdrcmplt = 0; + int s, len, loop_copy = 0, error = 0, hdrcmplt = 0; u_char esrc[6], edst[6]; register struct rtentry *rt; register struct fddi_header *fh; struct arpcom *ac = (struct arpcom *)ifp; + ALTQ_DECL(struct altq_pktattr pktattr;) + short mflags; if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) senderr(ENETDOWN); @@ -161,6 +163,13 @@ senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } #endif + + /* + * If the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); + switch (dst->sa_family) { #ifdef INET @@ -349,20 +358,22 @@ } } + mflags = m->m_flags; + len = m->m_pkthdr.len; s = splimp(); /* * Queue message on interface, and start output if interface * not yet active. */ - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); + IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); + if (error) { + /* mbuf is already freed */ splx(s); - senderr(ENOBUFS); + return (error); } - ifp->if_obytes += m->m_pkthdr.len; - if (m->m_flags & M_MCAST) + ifp->if_obytes += len; + if (mflags & M_MCAST) ifp->if_omcasts++; - IF_ENQUEUE(&ifp->if_snd, m); if ((ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); splx(s); diff -urN ../sys/net/if_loop.c ./net/if_loop.c --- ../sys/net/if_loop.c Fri Jan 24 06:06:44 2003 +++ ./net/if_loop.c Thu Apr 17 22:36:00 2003 @@ -90,6 +90,9 @@ static void lortrequest __P((int, struct rtentry *, struct rt_addrinfo *)); static void loopattach __P((void *)); +#ifdef ALTQ +static void lo_altqstart __P((struct ifnet *)); +#endif PSEUDO_SET(loopattach, if_loop); int looutput __P((struct ifnet *ifp, @@ -121,7 +124,11 @@ ifp->if_ioctl = loioctl; ifp->if_output = looutput; ifp->if_type = IFT_LOOP; - ifp->if_snd.ifq_maxlen = ifqmaxlen; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + IFQ_SET_READY(&ifp->if_snd); +#ifdef ALTQ + ifp->if_start = lo_altqstart; +#endif if_attach(ifp); bpfattach(ifp, DLT_NULL, sizeof(u_int)); } @@ -260,6 +267,38 @@ #endif } +#ifdef ALTQ + /* + * altq for loop is just for debugging. + * only used when called for loop interface (not for + * a simplex interface). + */ + if ((ALTQ_IS_ENABLED(&ifp->if_snd) || TBR_IS_ENABLED(&ifp->if_snd)) + && ifp->if_start == lo_altqstart) { + struct altq_pktattr pktattr; + int32_t *afp; + int error; + + /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, af, &pktattr); + + M_PREPEND(m, sizeof(int32_t), M_DONTWAIT); + if (m == 0) + return(ENOBUFS); + afp = mtod(m, int32_t *); + *afp = (int32_t)af; + + s = splimp(); + IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); + (*ifp->if_start)(ifp); + splx(s); + return (error); + } +#endif /* ALTQ */ + /* Deliver to upper layer protocol */ switch (af) { #ifdef INET @@ -312,6 +351,87 @@ splx(s); return (0); } + +#ifdef ALTQ +static void +lo_altqstart(ifp) + struct ifnet *ifp; +{ + struct ifqueue *ifq; + struct mbuf *m; + int32_t af, *afp; + int s, isr; + + while (1) { + s = splimp(); + IFQ_DEQUEUE(&ifp->if_snd, m); + splx(s); + if (m == NULL) + return; + + afp = mtod(m, int32_t *); + af = *afp; + m_adj(m, sizeof(int32_t)); + + switch (af) { +#ifdef INET + case AF_INET: + ifq = &ipintrq; + isr = NETISR_IP; + break; +#endif +#ifdef INET6 + case AF_INET6: + m->m_flags |= M_LOOP; + ifq = &ip6intrq; + isr = NETISR_IPV6; + break; +#endif +#ifdef IPX + case AF_IPX: + ifq = &ipxintrq; + isr = NETISR_IPX; + break; +#endif +#ifdef NS + case AF_NS: + ifq = &nsintrq; + isr = NETISR_NS; + break; +#endif +#ifdef ISO + case AF_ISO: + ifq = &clnlintrq; + isr = NETISR_ISO; + break; +#endif +#ifdef NETATALK + case AF_APPLETALK: + ifq = &atintrq2; + isr = NETISR_ATALK; + break; +#endif NETATALK + default: + printf("lo_altqstart: can't handle af%d\n", af); + m_freem(m); + return; + } + + s = splimp(); + if (IF_QFULL(ifq)) { + IF_DROP(ifq); + m_freem(m); + splx(s); + return; + } + IF_ENQUEUE(ifq, m); + schednetisr(isr); + ifp->if_ipackets++; + ifp->if_ibytes += m->m_pkthdr.len; + splx(s); + } +} +#endif /* ALTQ */ /* ARGSUSED */ static void diff -urN ../sys/net/if_ppp.c ./net/if_ppp.c --- ../sys/net/if_ppp.c Mon Apr 15 06:41:48 2002 +++ ./net/if_ppp.c Thu Apr 17 22:36:00 2003 @@ -145,6 +145,9 @@ static void ppp_ccp_closed __P((struct ppp_softc *)); static void ppp_inproc __P((struct ppp_softc *, struct mbuf *)); static void pppdumpm __P((struct mbuf *m0)); +#ifdef ALTQ +static void ppp_ifstart __P((struct ifnet *ifp)); +#endif /* * Some useful mbuf macros not in mbuf.h. @@ -207,10 +210,15 @@ sc->sc_if.if_hdrlen = PPP_HDRLEN; sc->sc_if.if_ioctl = pppsioctl; sc->sc_if.if_output = pppoutput; - sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN; +#ifdef ALTQ + sc->sc_if.if_softc = sc; + sc->sc_if.if_start = ppp_ifstart; +#endif + IFQ_SET_MAXLEN(&sc->sc_if.if_snd, IFQ_MAXLEN); sc->sc_inq.ifq_maxlen = IFQ_MAXLEN; sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN; sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_READY(&sc->sc_if.if_snd); if_attach(&sc->sc_if); bpfattach(&sc->sc_if, DLT_PPP, PPP_HDRLEN); } @@ -693,6 +701,7 @@ enum NPmode mode; int len; struct mbuf *m; + ALTQ_DECL(struct altq_pktattr pktattr;) if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0 || ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) { @@ -700,6 +709,8 @@ goto bad; } + IFQ_CLASSIFY(&ifp->if_snd, m0, dst->sa_family, &pktattr); + /* * Compute PPP header. */ @@ -835,16 +846,29 @@ sc->sc_npqtail = &m0->m_nextpkt; } else { /* fastq and if_snd are emptied at spl[soft]net now */ - ifq = (m0->m_flags & M_HIGHPRI)? &sc->sc_fastq: &ifp->if_snd; - if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) { - IF_DROP(ifq); + if ((m0->m_flags & M_HIGHPRI) +#ifdef ALTQ + && !ALTQ_IS_ENABLED(&sc->sc_if.if_snd) +#endif + ) { + ifq = &sc->sc_fastq; + if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) { + IF_DROP(ifq); + m_freem(m0); + error = ENOBUFS; + } + else { + IF_ENQUEUE(ifq, m0); + error = 0; + } + } else + IFQ_ENQUEUE(&sc->sc_if.if_snd, m0, &pktattr, error); + if (error) { splx(s); sc->sc_if.if_oerrors++; sc->sc_stats.ppp_oerrors++; - error = ENOBUFS; - goto bad; + return (error); } - IF_ENQUEUE(ifq, m0); (*sc->sc_start)(sc); } getmicrotime(&ifp->if_lastchange); @@ -871,6 +895,7 @@ struct mbuf *m, **mpp; struct ifqueue *ifq; enum NPmode mode; + int error; for (mpp = &sc->sc_npqueue; (m = *mpp) != NULL; ) { switch (PPP_PROTOCOL(mtod(m, u_char *))) { @@ -888,13 +913,27 @@ */ *mpp = m->m_nextpkt; m->m_nextpkt = NULL; - ifq = (m->m_flags & M_HIGHPRI)? &sc->sc_fastq: &sc->sc_if.if_snd; - if (IF_QFULL(ifq)) { - IF_DROP(ifq); + if ((m->m_flags & M_HIGHPRI) +#ifdef ALTQ + && !ALTQ_IS_ENABLED(&sc->sc_if.if_snd) +#endif + ) { + ifq = &sc->sc_fastq; + if (IF_QFULL(ifq)) { + IF_DROP(ifq); + m_freem(m); + error = ENOBUFS; + } + else { + IF_ENQUEUE(ifq, m); + error = 0; + } + } else + IFQ_ENQUEUE(&sc->sc_if.if_snd, m, NULL, error); + if (error) { sc->sc_if.if_oerrors++; sc->sc_stats.ppp_oerrors++; - } else - IF_ENQUEUE(ifq, m); + } break; case NPMODE_DROP: @@ -947,7 +986,7 @@ */ IF_DEQUEUE(&sc->sc_fastq, m); if (m == NULL) - IF_DEQUEUE(&sc->sc_if.if_snd, m); + IFQ_DEQUEUE(&sc->sc_if.if_snd, m); if (m == NULL) return NULL; @@ -1072,7 +1111,7 @@ for (i = 0; i < NPPP; ++i, ++sc) { s = splimp(); if (!(sc->sc_flags & SC_TBUSY) - && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) { + && (!IFQ_IS_EMPTY(&sc->sc_if.if_snd) || sc->sc_fastq.ifq_head)) { sc->sc_flags |= SC_TBUSY; splx(s); (*sc->sc_start)(sc); @@ -1570,3 +1609,19 @@ *bp = 0; printf("%s\n", buf); } + +#ifdef ALTQ +/* + * a wrapper to transmit a packet from if_start since ALTQ uses + * if_start to send a packet. + */ +static void +ppp_ifstart(ifp) + struct ifnet *ifp; +{ + struct ppp_softc *sc; + + sc = ifp->if_softc; + (*sc->sc_start)(sc); +} +#endif diff -urN ../sys/net/if_sl.c ./net/if_sl.c --- ../sys/net/if_sl.c Wed Feb 13 09:43:10 2002 +++ ./net/if_sl.c Thu Apr 17 22:36:00 2003 @@ -223,10 +223,11 @@ sc->sc_if.if_type = IFT_SLIP; sc->sc_if.if_ioctl = slioctl; sc->sc_if.if_output = sloutput; - sc->sc_if.if_snd.ifq_maxlen = 50; + IFQ_SET_MAXLEN(&sc->sc_if.if_snd, 50); sc->sc_fastq.ifq_maxlen = 32; sc->sc_if.if_linkmib = sc; sc->sc_if.if_linkmiblen = sizeof *sc; + IFQ_SET_READY(&sc->sc_if.if_snd); if_attach(&sc->sc_if); bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN); } @@ -489,7 +490,10 @@ register struct sl_softc *sc = &sl_softc[ifp->if_unit]; register struct ip *ip; register struct ifqueue *ifq; - int s; + int s, error; + ALTQ_DECL(struct altq_pktattr pktattr;) + + IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); /* * `Cannot happen' (see slioctl). Someday we will extend @@ -511,23 +515,33 @@ m_freem(m); return (EHOSTUNREACH); } - ifq = &sc->sc_if.if_snd; ip = mtod(m, struct ip *); if (sc->sc_if.if_flags & SC_NOICMP && ip->ip_p == IPPROTO_ICMP) { m_freem(m); return (ENETRESET); /* XXX ? */ } - if (ip->ip_tos & IPTOS_LOWDELAY) - ifq = &sc->sc_fastq; s = splimp(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); + if ((ip->ip_tos & IPTOS_LOWDELAY) +#ifdef ALTQ + && !ALTQ_IS_ENABLED(&sc->sc_if.if_snd) +#endif + ) { + ifq = &sc->sc_fastq; + if (IF_QFULL(ifq)) { + IF_DROP(ifq); + m_freem(m); + error = ENOBUFS; + } else { + IF_ENQUEUE(ifq, m); + error = 0; + } + } else + IFQ_ENQUEUE(&sc->sc_if.if_snd, m, &pktattr, error); + if (error) { splx(s); sc->sc_if.if_oerrors++; - return (ENOBUFS); + return (error); } - IF_ENQUEUE(ifq, m); if (sc->sc_ttyp->t_outq.c_cc == 0) slstart(sc->sc_ttyp); splx(s); @@ -580,7 +594,7 @@ if (m) sc->sc_if.if_omcasts++; /* XXX */ else - IF_DEQUEUE(&sc->sc_if.if_snd, m); + IFQ_DEQUEUE(&sc->sc_if.if_snd, m); splx(s); if (m == NULL) return 0; diff -urN ../sys/net/if_spppsubr.c ./net/if_spppsubr.c --- ../sys/net/if_spppsubr.c Thu Jul 4 00:44:41 2002 +++ ./net/if_spppsubr.c Thu Apr 17 22:36:00 2003 @@ -775,9 +775,10 @@ struct sppp *sp = (struct sppp*) ifp; struct ppp_header *h; struct ifqueue *ifq = NULL; - int s, rv = 0; + int s, len, rv = 0; int ipproto = PPP_IP; int debug = ifp->if_flags & IFF_DEBUG; + ALTQ_DECL(struct altq_pktattr pktattr;) s = splimp(); @@ -815,7 +816,13 @@ s = splimp(); } - ifq = &ifp->if_snd; +#ifdef ALTQ + /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); +#endif #ifdef INET if (dst->sa_family == AF_INET) { /* XXX Check mbuf length here? */ @@ -979,14 +986,27 @@ * Queue message on interface, and start output if interface * not yet active. */ - if (IF_QFULL (ifq)) { - IF_DROP (&ifp->if_snd); - m_freem (m); + len = m->m_pkthdr.len; + if (ifq != NULL +#ifdef ALTQ + && !ALTQ_IS_ENABLED(&ifp->if_snd) +#endif + ) { + if (IF_QFULL (ifq)) { + IF_DROP (&ifp->if_snd); + m_freem (m); + if (rv == 0) + rv = ENOBUFS; + } + IF_ENQUEUE (ifq, m); + } else + IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, rv); + if (rv != 0) { ++ifp->if_oerrors; splx (s); - return (rv? rv: ENOBUFS); + return (rv); } - IF_ENQUEUE (ifq, m); + if (! (ifp->if_flags & IFF_OACTIVE)) (*ifp->if_start) (ifp); @@ -995,7 +1015,7 @@ * The packet length includes header, FCS and 1 flag, * according to RFC 1333. */ - ifp->if_obytes += m->m_pkthdr.len + 3; + ifp->if_obytes += len + 3; splx (s); /* * Unlike in sppp_input(), we can always bump the timestamp @@ -1084,7 +1104,7 @@ { struct sppp *sp = (struct sppp*) ifp; - sppp_qflush (&sp->pp_if.if_snd); + IFQ_PURGE(&sp->pp_if.if_snd); sppp_qflush (&sp->pp_fastq); sppp_qflush (&sp->pp_cpq); } @@ -1100,7 +1120,7 @@ s = splimp(); empty = !sp->pp_fastq.ifq_head && !sp->pp_cpq.ifq_head && - !sp->pp_if.if_snd.ifq_head; + IFQ_IS_EMPTY(&sp->pp_if.if_snd); splx(s); return (empty); } @@ -1127,7 +1147,7 @@ (sppp_ncp_check(sp) || sp->pp_mode == IFF_CISCO)) { IF_DEQUEUE(&sp->pp_fastq, m); if (m == NULL) - IF_DEQUEUE (&sp->pp_if.if_snd, m); + IFQ_DEQUEUE (&sp->pp_if.if_snd, m); } splx(s); return m; @@ -1149,7 +1169,7 @@ if (m == NULL && (sp->pp_phase == PHASE_NETWORK || sp->pp_mode == IFF_CISCO)) if ((m = sp->pp_fastq.ifq_head) == NULL) - m = sp->pp_if.if_snd.ifq_head; + IFQ_POLL(&sp->pp_if.if_snd, m); splx (s); return (m); } diff -urN ../sys/net/if_tun.c ./net/if_tun.c --- ../sys/net/if_tun.c Wed Feb 13 09:43:11 2002 +++ ./net/if_tun.c Thu Apr 17 22:36:01 2003 @@ -65,6 +65,9 @@ struct rtentry *rt)); static int tunifioctl __P((struct ifnet *, u_long, caddr_t)); static int tuninit __P((struct ifnet *)); +#ifdef ALTQ +static void tunstart __P((struct ifnet *)); +#endif static d_open_t tunopen; static d_close_t tunclose; @@ -119,9 +122,13 @@ ifp->if_mtu = TUNMTU; ifp->if_ioctl = tunifioctl; ifp->if_output = tunoutput; +#ifdef ALTQ + ifp->if_start = tunstart; +#endif ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; ifp->if_type = IFT_PPP; - ifp->if_snd.ifq_maxlen = ifqmaxlen; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + IFQ_SET_READY(&ifp->if_snd); ifp->if_softc = sc; if_attach(ifp); bpfattach(ifp, DLT_NULL, sizeof(u_int)); @@ -174,7 +181,6 @@ register int s; struct tun_softc *tp; struct ifnet *ifp; - struct mbuf *m; tp = dev->si_drv1; ifp = &tp->tun_if; @@ -185,13 +191,9 @@ /* * junk all pending output */ - do { - s = splimp(); - IF_DEQUEUE(&ifp->if_snd, m); - splx(s); - if (m) - m_freem(m); - } while (m); + s = splimp(); + IFQ_PURGE(&ifp->if_snd); + splx(s); if (ifp->if_flags & IFF_UP) { s = splimp(); @@ -315,7 +317,8 @@ struct rtentry *rt; { struct tun_softc *tp = ifp->if_softc; - int s; + int s, error, len; + ALTQ_DECL(struct altq_pktattr pktattr;) TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit); @@ -326,6 +329,12 @@ return EHOSTDOWN; } + /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m0, dst->sa_family, &pktattr); + /* BPF write needs to be handled specially */ if (dst->sa_family == AF_UNSPEC) { dst->sa_family = *(mtod(m0, int *)); @@ -392,16 +401,15 @@ } } + len = m0->m_pkthdr.len; s = splimp(); - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); - m_freem(m0); + IFQ_ENQUEUE(&ifp->if_snd, m0, &pktattr, error); + if (error) { splx(s); ifp->if_collisions++; - return ENOBUFS; + return (error); } - ifp->if_obytes += m0->m_pkthdr.len; - IF_ENQUEUE(&ifp->if_snd, m0); + ifp->if_obytes += len; splx(s); ifp->if_opackets++; @@ -496,8 +504,10 @@ break; case FIONREAD: s = splimp(); - if (tp->tun_if.if_snd.ifq_head) { - struct mbuf *mb = tp->tun_if.if_snd.ifq_head; + if (!IFQ_IS_EMPTY(&tp->tun_if.if_snd)) { + struct mbuf *mb; + + IFQ_POLL(&tp->tun_if.if_snd, mb); for( *(int *)data = 0; mb != 0; mb = mb->m_next) *(int *)data += mb->m_len; } else @@ -552,7 +562,7 @@ s = splimp(); do { - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_DEQUEUE(&ifp->if_snd, m0); if (m0 == 0) { if (flag & IO_NDELAY) { splx(s); @@ -709,7 +719,7 @@ TUNDEBUG("%s%d: tunpoll\n", ifp->if_name, ifp->if_unit); if (events & (POLLIN | POLLRDNORM)) { - if (ifp->if_snd.ifq_len > 0) { + if (!IFQ_IS_EMPTY(&ifp->if_snd)) { TUNDEBUG("%s%d: tunpoll q=%d\n", ifp->if_name, ifp->if_unit, ifp->if_snd.ifq_len); revents |= events & (POLLIN | POLLRDNORM); @@ -725,3 +735,33 @@ splx(s); return (revents); } + +#ifdef ALTQ +/* + * Start packet transmission on the interface. + * when the interface queue is rate-limited by ALTQ or TBR, + * if_start is needed to drain packets from the queue in order + * to notify readers when outgoing packets become ready. + */ +static void +tunstart(ifp) + struct ifnet *ifp; +{ + struct tun_softc *tp = ifp->if_softc; + struct mbuf *m; + + if (!ALTQ_IS_ENABLED(&ifp->if_snd) && !TBR_IS_ENABLED(&ifp->if_snd)) + return; + + IFQ_POLL(&ifp->if_snd, m); + if (m != NULL) { + if (tp->tun_flags & TUN_RWAIT) { + tp->tun_flags &= ~TUN_RWAIT; + wakeup((caddr_t)tp); + } + if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) + pgsigio(tp->tun_sigio, SIGIO, 0); + selwakeup(&tp->tun_rsel); + } +} +#endif diff -urN ../sys/net/if_var.h ./net/if_var.h --- ../sys/net/if_var.h Fri Jun 28 21:36:54 2002 +++ ./net/if_var.h Thu Apr 17 22:36:01 2003 @@ -75,6 +75,9 @@ #endif #include /* get TAILQ macros */ +#if 1 /* ALTQ */ +#include +#endif #ifdef _KERNEL #include @@ -176,7 +179,11 @@ (void *); int (*if_resolvemulti) /* validate/resolve multicast */ (struct ifnet *, struct sockaddr **, struct sockaddr *); +#if 1 /* ALTQ */ + struct ifaltq if_snd; /* output queue (includes altq) */ +#else struct ifqueue if_snd; /* output queue */ +#endif struct ifqueue *if_poll_slowq; /* input queue for slow devices */ struct ifprefixhead if_prefixhead; /* list of prefixes per if */ }; @@ -255,6 +262,17 @@ (ifq)->ifq_len--; \ } \ } +#define IF_POLL(ifq, m) ((m) = (ifq)->ifq_head) +#define IF_PURGE(ifq) \ +while (1) { \ + struct mbuf *m0; \ + IF_DEQUEUE((ifq), m0); \ + if (m0 == NULL) \ + break; \ + else \ + m_freem(m0); \ +} +#define IF_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) #ifdef _KERNEL @@ -297,6 +315,131 @@ */ #define IF_MINMTU 72 #define IF_MAXMTU 65535 + +#endif /* _KERNEL */ + +#ifdef _KERNEL +#ifdef ALTQ +#define ALTQ_DECL(x) x + +#define IFQ_ENQUEUE(ifq, m, pattr, err) \ +do { \ + if (ALTQ_IS_ENABLED((ifq))) \ + ALTQ_ENQUEUE((ifq), (m), (pattr), (err)); \ + else { \ + if (IF_QFULL((ifq))) { \ + m_freem((m)); \ + (err) = ENOBUFS; \ + } else { \ + IF_ENQUEUE((ifq), (m)); \ + (err) = 0; \ + } \ + } \ + if ((err)) \ + (ifq)->ifq_drops++; \ +} while (0) + +#define IFQ_DEQUEUE(ifq, m) \ +do { \ + if (TBR_IS_ENABLED((ifq))) \ + (m) = tbr_dequeue((ifq), ALTDQ_REMOVE); \ + else if (ALTQ_IS_ENABLED((ifq))) \ + ALTQ_DEQUEUE((ifq), (m)); \ + else \ + IF_DEQUEUE((ifq), (m)); \ +} while (0) + +#define IFQ_POLL(ifq, m) \ +do { \ + if (TBR_IS_ENABLED((ifq))) \ + (m) = tbr_dequeue((ifq), ALTDQ_POLL); \ + else if (ALTQ_IS_ENABLED((ifq))) \ + ALTQ_POLL((ifq), (m)); \ + else \ + IF_POLL((ifq), (m)); \ +} while (0) + +#define IFQ_PURGE(ifq) \ +do { \ + if (ALTQ_IS_ENABLED((ifq))) \ + ALTQ_PURGE((ifq)); \ + else \ + IF_PURGE((ifq)); \ +} while (0) + +#define IFQ_SET_READY(ifq) \ + do { ((ifq)->altq_flags |= ALTQF_READY); } while (0) + +#define IFQ_CLASSIFY(ifq, m, af, pa) \ +do { \ + if (ALTQ_IS_ENABLED((ifq))) { \ + if (ALTQ_NEEDS_CLASSIFY((ifq))) \ + (pa)->pattr_class = (*(ifq)->altq_classify) \ + ((ifq)->altq_clfier, (m), (af)); \ + (pa)->pattr_af = (af); \ + (pa)->pattr_hdr = mtod((m), caddr_t); \ + } \ +} while (0) + +#else /* !ALTQ */ +#define ALTQ_DECL(x) /* nothing */ + +#define IFQ_ENQUEUE(ifq, m, pattr, err) \ +do { \ + if (IF_QFULL((ifq))) { \ + m_freem((m)); \ + (err) = ENOBUFS; \ + } else { \ + IF_ENQUEUE((ifq), (m)); \ + (err) = 0; \ + } \ + if ((err)) \ + (ifq)->ifq_drops++; \ +} while (0) + +#define IFQ_DEQUEUE(ifq, m) IF_DEQUEUE((ifq), (m)) + +#define IFQ_POLL(ifq, m) IF_POLL((ifq), (m)) + +#define IFQ_PURGE(ifq) \ +while (1) { \ + struct mbuf *m0; \ + IF_DEQUEUE((ifq), m0); \ + if (m0 == NULL) \ + break; \ + else \ + m_freem(m0); \ +} + +#define IFQ_SET_READY(ifq) /* nothing */ +#define IFQ_CLASSIFY(ifq, m, af, pa) /* nothing */ + +#endif /* !ALTQ */ + +#define IFQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) +#define IFQ_INC_LEN(ifq) ((ifq)->ifq_len++) +#define IFQ_DEC_LEN(ifq) (--(ifq)->ifq_len) +#define IFQ_INC_DROPS(ifq) ((ifq)->ifq_drops++) +#define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len)) + +#define IFQ_HANDOFF(ifp, m, pattr, err) \ +do { \ + int len, s; \ + short mflags; \ + \ + len = (m)->m_pkthdr.len; \ + mflags = (m)->m_flags; \ + s = splimp(); \ + IFQ_ENQUEUE(&(ifp)->if_snd, m, pattr, err); \ + if ((err) == 0) { \ + (ifp)->if_obytes += len; \ + if (mflags & M_MCAST) \ + (ifp)->if_omcasts++; \ + if (((ifp)->if_flags & IFF_OACTIVE) == 0) \ + (*(ifp)->if_start)(ifp); \ + } \ + splx(s); \ +} while (0) #endif /* _KERNEL */ diff -urN ../sys/net/if_vlan.c ./net/if_vlan.c --- ../sys/net/if_vlan.c Sat Feb 15 07:25:58 2003 +++ ./net/if_vlan.c Thu Apr 17 22:36:01 2003 @@ -274,7 +274,8 @@ ifp->if_start = vlan_start; ifp->if_ioctl = vlan_ioctl; ifp->if_output = ether_output; - ifp->if_snd.ifq_maxlen = ifqmaxlen; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + IFQ_SET_READY(&ifp->if_snd); ether_ifattach(ifp, ETHER_BPF_SUPPORTED); /* Now undo some of the damage... */ ifp->if_data.ifi_type = IFT_L2VLAN; @@ -315,13 +316,16 @@ struct ifnet *p; struct ether_vlan_header *evl; struct mbuf *m; + int error, len; + short mflags; + ALTQ_DECL(struct altq_pktattr pktattr;) ifv = ifp->if_softc; p = ifv->ifv_p; ifp->if_flags |= IFF_OACTIVE; for (;;) { - IF_DEQUEUE(&ifp->if_snd, m); + IFQ_DEQUEUE(&ifp->if_snd, m); if (m == 0) break; if (ifp->if_bpf) @@ -338,6 +342,16 @@ continue; } +#ifdef ALTQ + /* + * If ALTQ is enabled on the parent interface, do + * classification; the queueing discipline might + * not require classification, but might require + * the address family/header pointer in the pktattr. + */ + if (ALTQ_IS_ENABLED(&p->if_snd)) + altq_etherclassify(&p->if_snd, m, &pktattr); +#endif /* * If the LINK0 flag is set, it means the underlying interface * can do VLAN tag insertion itself and doesn't require us to @@ -395,17 +409,17 @@ * Send it, precisely as ether_output() would have. * We are already running at splimp. */ - if (IF_QFULL(&p->if_snd)) { - IF_DROP(&p->if_snd); - /* XXX stats */ + mflags = m->m_flags; + len = m->m_pkthdr.len; + IFQ_ENQUEUE(&p->if_snd, m, NULL, error); + if (error) { + /* mbuf is already freed */ ifp->if_oerrors++; - m_freem(m); continue; } - IF_ENQUEUE(&p->if_snd, m); ifp->if_opackets++; - p->if_obytes += m->m_pkthdr.len; - if (m->m_flags & M_MCAST) + p->if_obytes += len; + if (mflags & M_MCAST) p->if_omcasts++; if ((p->if_flags & IFF_OACTIVE) == 0) p->if_start(p); diff -urN ../sys/net/ppp_tty.c ./net/ppp_tty.c --- ../sys/net/ppp_tty.c Wed Feb 13 09:43:11 2002 +++ ./net/ppp_tty.c Thu Apr 17 22:36:01 2003 @@ -784,6 +784,15 @@ if (tp->t_oproc != NULL) (*tp->t_oproc)(tp); +#ifdef ALTQ + /* + * if ALTQ is enabled, don't invoke NETISR_PPP. + * pppintr() could loop without doing anything useful + * under rate-limiting. + */ + if (ALTQ_IS_ENABLED(&sc->sc_if.if_snd)) + return 0; +#endif /* * If the transmit queue has drained and the tty has not hung up * or been disconnected from the ppp unit, then tell if_ppp.c that diff -urN ../sys/netinet/if_atm.c ./netinet/if_atm.c --- ../sys/netinet/if_atm.c Thu Dec 20 19:30:18 2001 +++ ./netinet/if_atm.c Thu Apr 17 22:36:01 2003 @@ -95,7 +95,9 @@ switch (req) { case RTM_RESOLVE: /* resolve: only happens when cloning */ +#ifdef DIAGNOSTIC printf("atm_rtrequest: RTM_RESOLVE request detected?\n"); +#endif break; case RTM_ADD: @@ -116,12 +118,16 @@ } if ((rt->rt_flags & RTF_CLONING) != 0) { +#ifdef DIAGNOSTIC printf("atm_rtrequest: cloning route detected?\n"); +#endif break; } if (gate->sa_family != AF_LINK || gate->sa_len < sizeof(null_sdl)) { +#ifdef DIAGNOSTIC log(LOG_DEBUG, "atm_rtrequest: bad gateway value"); +#endif break; } diff -urN ../sys/netinet/ip.h ./netinet/ip.h --- ../sys/netinet/ip.h Thu Dec 23 04:13:20 1999 +++ ./netinet/ip.h Thu Apr 17 22:36:01 2003 @@ -89,10 +89,11 @@ #define IPTOS_THROUGHPUT 0x08 #define IPTOS_RELIABILITY 0x04 #define IPTOS_MINCOST 0x02 -/* ECN bits proposed by Sally Floyd */ +#if 1 +/* ECN RFC3168 obsoletes RFC2481, and these will be deprecated soon. */ #define IPTOS_CE 0x01 /* congestion experienced */ #define IPTOS_ECT 0x02 /* ECN-capable transport */ - +#endif /* * Definitions for IP precedence (also in ip_tos) (hopefully unused) @@ -105,6 +106,16 @@ #define IPTOS_PREC_IMMEDIATE 0x40 #define IPTOS_PREC_PRIORITY 0x20 #define IPTOS_PREC_ROUTINE 0x00 + +/* + * ECN (Explicit Congestion Notification) codepoints in RFC3168 + * mapped to the lower 2 bits of the TOS field. + */ +#define IPTOS_ECN_NOTECT 0x00 /* not-ECT */ +#define IPTOS_ECN_ECT1 0x01 /* ECN-capable transport (1) */ +#define IPTOS_ECN_ECT0 0x02 /* ECN-capable transport (0) */ +#define IPTOS_ECN_CE 0x03 /* congestion experienced */ +#define IPTOS_ECN_MASK 0x03 /* ECN field mask */ /* * Definitions for options. diff -urN ../sys/netinet/ip_input.c ./netinet/ip_input.c --- ../sys/netinet/ip_input.c Fri Mar 7 16:01:28 2003 +++ ./netinet/ip_input.c Thu Apr 17 22:36:01 2003 @@ -396,6 +396,11 @@ goto bad; } +#ifdef ALTQ + if (altq_input != NULL && (*altq_input)(m, AF_INET) == 0) + /* packet is dropped by traffic conditioner */ + return; +#endif /* * Convert fields to host representation. */ diff -urN ../sys/netinet/ip_mroute.c ./netinet/ip_mroute.c --- ../sys/netinet/ip_mroute.c Fri Jan 24 06:06:45 2003 +++ ./netinet/ip_mroute.c Thu Apr 17 23:43:07 2003 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1787,6 +1788,12 @@ struct sockaddr_in rsvp_src = { sizeof rsvp_src, AF_INET }; int s; struct ifnet *ifp; +#ifdef ALTQ + /* support IP_RECVIF used by rsvpd rel4.2a1 */ + struct inpcb *inp; + struct socket *so; + struct mbuf *opts; +#endif if (rsvpdebug) printf("rsvp_input: rsvp_on %d\n",rsvp_on); @@ -1816,7 +1823,11 @@ if (viftable[vifi].v_ifp == ifp) break; +#ifdef ALTQ + if (vifi == numvifs || (so = viftable[vifi].v_rsvpd) == NULL) { +#else if (vifi == numvifs || viftable[vifi].v_rsvpd == NULL) { +#endif /* * If the old-style non-vif-associated socket is set, * then use it. Otherwise, drop packet since there @@ -1842,6 +1853,26 @@ printf("rsvp_input: m->m_len = %d, sbspace() = %ld\n", m->m_len,sbspace(&(viftable[vifi].v_rsvpd->so_rcv))); +#ifdef ALTQ + opts = NULL; + inp = (struct inpcb *)so->so_pcb; + if (inp->inp_flags & INP_CONTROLOPTS || + inp->inp_socket->so_options & SO_TIMESTAMP) + ip_savecontrol(inp, &opts, ip, m); + if (sbappendaddr(&so->so_rcv, + (struct sockaddr *)&rsvp_src,m, opts) == 0) { + m_freem(m); + if (opts) + m_freem(opts); + if (rsvpdebug) + printf("rsvp_input: Failed to append to socket\n"); + } + else { + sorwakeup(so); + if (rsvpdebug) + printf("rsvp_input: send packet up\n"); + } +#else /* !ALTQ */ if (socket_send(viftable[vifi].v_rsvpd, m, &rsvp_src) < 0) { if (rsvpdebug) printf("rsvp_input: Failed to append to socket\n"); @@ -1849,6 +1880,7 @@ if (rsvpdebug) printf("rsvp_input: send packet up\n"); } +#endif /* !ALTQ */ splx(s); } diff -urN ../sys/netinet/ip_output.c ./netinet/ip_output.c --- ../sys/netinet/ip_output.c Thu Jan 30 14:53:28 2003 +++ ./netinet/ip_output.c Thu Apr 17 22:36:01 2003 @@ -415,6 +415,12 @@ } } #endif /* notdef */ +#ifdef ALTQ + /* + * disable packet drop hack. + * packetdrop should be done by queueing. + */ +#else /* !ALTQ */ /* * Verify that we have any chance at all of being able to queue * the packet or packet fragments @@ -425,6 +431,7 @@ ipstat.ips_odropped++; goto bad; } +#endif /* !ALTQ */ /* * Look for broadcast address and diff -urN ../sys/netinet6/ip6_input.c ./netinet6/ip6_input.c --- ../sys/netinet6/ip6_input.c Fri Jan 24 14:11:35 2003 +++ ./netinet6/ip6_input.c Thu Apr 17 22:36:01 2003 @@ -387,6 +387,12 @@ return; } +#ifdef ALTQ + if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) { + /* packet is dropped by traffic conditioner */ + return; + } +#endif /* * Check against address spoofing/corruption. */ diff -urN ../sys/pci/if_dc.c ./pci/if_dc.c --- ../sys/pci/if_dc.c Thu Mar 6 03:42:33 2003 +++ ./pci/if_dc.c Thu Apr 17 22:36:01 2003 @@ -2042,7 +2042,8 @@ ifp->if_watchdog = dc_watchdog; ifp->if_init = dc_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = DC_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, DC_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); /* * Do MII setup. If this is a 21143, check for a PHY on the @@ -2730,7 +2731,7 @@ if (mii->mii_media_status & IFM_ACTIVE && IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { sc->dc_link++; - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) dc_start(ifp); } } @@ -2935,7 +2936,7 @@ /* Re-enable interrupts. */ CSR_WRITE_4(sc, DC_IMR, DC_INTRS); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) dc_start(ifp); return; @@ -2999,6 +3000,11 @@ sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_FINT; if (sc->dc_flags & DC_TX_USE_TX_INTR && sc->dc_cdata.dc_tx_cnt > 64) sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_FINT; +#ifdef ALTQ + else if ((sc->dc_flags & DC_TX_USE_TX_INTR) && + TBR_IS_ENABLED(&sc->arpcom.ac_if.if_snd)) + sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_FINT; +#endif sc->dc_ldata->dc_tx_list[*txidx].dc_status = DC_TXSTAT_OWN; *txidx = frag; @@ -3047,7 +3053,7 @@ { struct dc_softc *sc; struct mbuf *m_head = NULL; - int idx; + int idx, coalesced; sc = ifp->if_softc; @@ -3060,26 +3066,38 @@ idx = sc->dc_cdata.dc_tx_prod; while(sc->dc_cdata.dc_tx_chain[idx] == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; if (sc->dc_flags & DC_TX_COALESCE && m_head->m_next != NULL) { /* only coalesce if have >1 mbufs */ +#ifdef ALTQ + /* note: dc_coal breaks the poll-and-dequeue rule. + * if dc_coal fails, we lose the packet. + */ +#endif + IFQ_DEQUEUE(&ifp->if_snd, m_head); if (dc_coal(sc, &m_head)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } - } + coalesced = 1; + } else + coalesced = 0; if (dc_encap(sc, m_head, &idx)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } + /* now we are committed to transmit the packet */ + if (coalesced) { + /* if mbuf is coalesced, it is already dequeued */ + } else + IFQ_DEQUEUE(&ifp->if_snd, m_head); + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -3092,6 +3110,8 @@ break; } } + if (idx == sc->dc_cdata.dc_tx_prod) + return; /* Transmit */ sc->dc_cdata.dc_tx_prod = idx; @@ -3410,7 +3430,7 @@ dc_reset(sc); dc_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) dc_start(ifp); return; diff -urN ../sys/pci/if_de.c ./pci/if_de.c --- ../sys/pci/if_de.c Sat Aug 5 08:25:09 2000 +++ ./pci/if_de.c Thu Apr 17 22:36:01 2003 @@ -4135,6 +4135,11 @@ #else struct mbuf *m0; #endif +#if 1 /* ALTQ */ + struct ifnet *ifp = &sc->tulip_if; + struct mbuf *ombuf = m; + int compressed = 0; +#endif #if defined(TULIP_DEBUG) if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) { @@ -4285,6 +4290,26 @@ * entries that we can use for one packet, so we have * recopy it into one mbuf and then try again. */ +#if 1 /* ALTQ */ + struct mbuf *tmp; + /* + * tulip_mbuf_compress() frees the original mbuf. + * thus, we have to remove the mbuf from the queue + * before calling it. + * we don't have to worry about space shortage + * after compressing the mbuf since the compressed + * mbuf will take only two segs. + */ + if (compressed) { + /* should not happen */ + printf("tulip_txput: compress called twice!\n"); + goto finish; + } + IFQ_DEQUEUE(&ifp->if_snd, tmp); + if (tmp != ombuf) + panic("tulip_txput: different mbuf dequeued!"); + compressed = 1; +#endif m = tulip_mbuf_compress(m); if (m == NULL) goto finish; @@ -4346,6 +4371,16 @@ * The descriptors have been filled in. Now get ready * to transmit. */ +#if 1 /* ALTQ */ + if (!compressed && (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) { + /* remove the mbuf from the queue */ + struct mbuf *tmp; + IFQ_DEQUEUE(&ifp->if_snd, tmp); + if (tmp != ombuf) + panic("tulip_txput: different mbuf dequeued!"); + } +#endif + IF_ENQUEUE(&sc->tulip_txq, m); m = NULL; @@ -4693,6 +4728,14 @@ return error; } +#if 1 /* ALTQ */ +/* + * the original dequeueing policy is dequeue-and-prepend if something + * goes wrong. when altq is used, it is changed to peek-and-dequeue. + * the modification becomes a bit complicated since tulip_txput() might + * copy and modify the mbuf passed. + */ +#endif /* * These routines gets called at device spl (from ether_output). This might * pose a problem for TULIP_USE_SOFTINTR if ether_output is called at @@ -4711,15 +4754,23 @@ if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP) tulip_txput_setup(sc); - while (sc->tulip_if.if_snd.ifq_head != NULL) { - struct mbuf *m; - IF_DEQUEUE(&sc->tulip_if.if_snd, m); - if ((m = tulip_txput(sc, m)) != NULL) { - IF_PREPEND(&sc->tulip_if.if_snd, m); + while (!IFQ_IS_EMPTY(&sc->tulip_if.if_snd)) { + struct mbuf *m, *m0; + IFQ_POLL(&sc->tulip_if.if_snd, m); + if (m == NULL) + break; + if ((m0 = tulip_txput(sc, m)) != NULL) { + if (m0 != m) + /* should not happen */ + printf("tulip_if_start: txput failed!\n"); break; } } - if (sc->tulip_if.if_snd.ifq_head == NULL) +#ifdef ALTQ + if (0) /* don't switch to the one packet mode */ +#else + if (IFQ_IS_EMPTY(&sc->tulip_if.if_snd)) +#endif sc->tulip_if.if_start = tulip_ifstart_one; } @@ -4734,11 +4785,13 @@ tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc; if ((sc->tulip_if.if_flags & IFF_RUNNING) - && sc->tulip_if.if_snd.ifq_head != NULL) { - struct mbuf *m; - IF_DEQUEUE(&sc->tulip_if.if_snd, m); - if ((m = tulip_txput(sc, m)) != NULL) - IF_PREPEND(&sc->tulip_if.if_snd, m); + && !IFQ_IS_EMPTY(&sc->tulip_if.if_snd)) { + struct mbuf *m, *m0; + IFQ_POLL(&sc->tulip_if.if_snd, m); + if (m != NULL && (m0 = tulip_txput(sc, m)) != NULL) + if (m0 != m) + /* should not happen */ + printf("tulip_if_start_one: txput failed!\n"); } TULIP_PERFEND(ifstart_one); } @@ -4844,7 +4897,8 @@ ifp->if_watchdog = tulip_ifwatchdog; ifp->if_timer = 1; ifp->if_output = ether_output; - + IFQ_SET_READY(&ifp->if_snd); + printf("%s%d: %s%s pass %d.%d%s\n", sc->tulip_name, sc->tulip_unit, sc->tulip_boardid, @@ -4874,8 +4928,8 @@ tulip_reset(sc); + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); ether_ifattach(&(sc)->tulip_if, ETHER_BPF_SUPPORTED); - ifp->if_snd.ifq_maxlen = ifqmaxlen; } #if defined(TULIP_BUS_DMA) diff -urN ../sys/pci/if_en_pci.c ./pci/if_en_pci.c --- ../sys/pci/if_en_pci.c Sun Aug 22 07:10:49 1999 +++ ./pci/if_en_pci.c Thu Apr 17 22:36:01 2003 @@ -45,19 +45,17 @@ * thanks to Matt Thomas for figuring out FreeBSD vs NetBSD vs etc.. diffs. */ -#include "en.h" - #include #include #include -#if defined(__FreeBSD__) -#include -#endif #include #include +#include +#include +#include +#include #include /* for DELAY */ - #include #include @@ -71,9 +69,10 @@ * prototypes */ -static void en_pci_attach __P((pcici_t, int)); -static const char *en_pci_probe __P((pcici_t, pcidi_t)); -static void en_pci_shutdown __P((void *, int)); +static int en_pci_probe __P((device_t)); +static int en_pci_attach __P((device_t)); +static int en_pci_detach __P((device_t)); +static int en_pci_shutdown __P((device_t)); /* * local structures @@ -83,43 +82,20 @@ /* bus independent stuff */ struct en_softc esc; /* includes "device" structure */ - /* PCI bus glue */ - void *sc_ih; /* interrupt handle */ - pci_chipset_tag_t en_pc; /* for PCI calls */ - pcici_t en_confid; /* config id */ + /* freebsd newbus glue */ + struct resource *res; /* resource descriptor for registers */ + struct resource *irq; /* resource descriptor for interrupt */ + void *ih; /* interrupt handle */ }; #if !defined(MIDWAY_ENIONLY) -static void eni_get_macaddr __P((struct en_pci_softc *)); +static void eni_get_macaddr __P((device_t, struct en_pci_softc *)); #endif #if !defined(MIDWAY_ADPONLY) static void adp_get_macaddr __P((struct en_pci_softc *)); #endif /* - * pointers to softcs (we alloc) - */ - -static struct en_pci_softc *enpcis[NEN] = {0}; -extern struct cfdriver en_cd; - -/* - * autoconfig structures - */ - -static u_long en_pci_count; - -static struct pci_device endevice = { - "en", - en_pci_probe, - en_pci_attach, - &en_pci_count, - NULL, -}; - -COMPAT_PCI_DRIVER (en, endevice); - -/* * local defines (PCI specific stuff) */ @@ -194,94 +170,104 @@ * autoconfig stuff */ -static const char *en_pci_probe(config_id, device_id) - -pcici_t config_id; -pcidi_t device_id; - +static int +en_pci_probe(device_t dev) { + switch (pci_get_vendor(dev)) { #if !defined(MIDWAY_ADPONLY) - if (PCI_VENDOR(device_id) == PCI_VENDOR_EFFICIENTNETS && - (PCI_CHIPID(device_id) == PCI_PRODUCT_EFFICIENTNETS_ENI155PF || - PCI_CHIPID(device_id) == PCI_PRODUCT_EFFICIENTNETS_ENI155PA)) - return "Efficient Networks ENI-155p"; + case PCI_VENDOR_EFFICIENTNETS: + switch (pci_get_device(dev)) { + case PCI_PRODUCT_EFFICIENTNETS_ENI155PF: + case PCI_PRODUCT_EFFICIENTNETS_ENI155PA: + device_set_desc(dev, "Efficient Networks ENI-155p"); + return 0; + } + break; #endif - #if !defined(MIDWAY_ENIONLY) - if (PCI_VENDOR(device_id) == PCI_VENDOR_ADP && - (PCI_CHIPID(device_id) == PCI_PRODUCT_ADP_AIC5900 || - PCI_CHIPID(device_id) == PCI_PRODUCT_ADP_AIC5905)) - return "Adaptec 155 ATM"; + case PCI_VENDOR_ADP: + switch (pci_get_device(dev)) { + case PCI_PRODUCT_ADP_AIC5900: + case PCI_PRODUCT_ADP_AIC5905: + device_set_desc(dev, "Adaptec 155 ATM"); + return 0; + } + break; #endif - - return 0; + } + return ENXIO; } -static void en_pci_attach(config_id, unit) - -pcici_t config_id; -int unit; - +static int +en_pci_attach(device_t dev) { struct en_softc *sc; struct en_pci_softc *scp; - pcidi_t device_id; - int retval; - vm_offset_t pa; - - if (unit >= NEN) { - printf("en%d: not configured; kernel is built for only %d device%s.\n", - unit, NEN, NEN == 1 ? "" : "s"); - return; - } + u_long val; + int rid, s, unit, error = 0; - scp = (struct en_pci_softc *) malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT); - if (scp == NULL) - return; + sc = device_get_softc(dev); + scp = (struct en_pci_softc *)sc; bzero(scp, sizeof(*scp)); /* zero */ - sc = &scp->esc; - retval = pci_map_mem(config_id, PCI_CBMA, (vm_offset_t *) &sc->en_base, &pa); + s = splimp(); - if (!retval) { - free((caddr_t) scp, M_DEVBUF); - return; - } - enpcis[unit] = scp; /* lock it in */ - en_cd.cd_devs[unit] = sc; /* fake a cfdriver structure */ - en_cd.cd_ndevs = NEN; - snprintf(sc->sc_dev.dv_xname, sizeof(sc->sc_dev.dv_xname), "en%d", unit); - sc->enif.if_unit = unit; - sc->enif.if_name = "en"; - scp->en_confid = config_id; + /* + * Enable bus mastering. + */ + val = pci_read_config(dev, PCIR_COMMAND, 2); + val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); + pci_write_config(dev, PCIR_COMMAND, val, 2); /* - * figure out if we are an adaptec card or not. - * XXX: why do we have to re-read PC_ID_REG when en_pci_probe already - * had that info? + * Map control/status registers. */ + rid = PCI_CBMA; + scp->res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, + 0, ~0, 1, RF_ACTIVE); + if (!scp->res) { + device_printf(dev, "could not map memory\n"); + error = ENXIO; + goto fail; + } - device_id = pci_conf_read(config_id, PCI_ID_REG); - sc->is_adaptec = (PCI_VENDOR(device_id) == PCI_VENDOR_ADP) ? 1 : 0; + sc->en_memt = rman_get_bustag(scp->res); + sc->en_base = rman_get_bushandle(scp->res); /* - * Add shutdown hook so that DMA is disabled prior to reboot. Not - * doing so could allow DMA to corrupt kernel memory during the - * reboot before the driver initializes. + * Allocate our interrupt. */ - EVENTHANDLER_REGISTER(shutdown_post_sync, en_pci_shutdown, scp, - SHUTDOWN_PRI_DEFAULT); + rid = 0; + scp->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, + RF_SHAREABLE | RF_ACTIVE); + if (scp->irq == NULL) { + device_printf(dev, "could not map interrupt\n"); + bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); + error = ENXIO; + goto fail; + } - if (!pci_map_int(config_id, en_intr, (void *) sc, &net_imask)) { - printf("%s: couldn't establish interrupt\n", sc->sc_dev.dv_xname); - return; + error = bus_setup_intr(dev, scp->irq, INTR_TYPE_NET, + en_intr, sc, &scp->ih); + if (error) { + device_printf(dev, "could not setup irq\n"); + bus_release_resource(dev, SYS_RES_IRQ, 0, scp->irq); + bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); + goto fail; } - sc->ipl = 1; /* XXX */ + sc->ipl = 1; /* XXX (required to enable interrupt on midway) */ + + unit = device_get_unit(dev); + snprintf(sc->sc_dev.dv_xname, sizeof(sc->sc_dev.dv_xname), "en%d", unit); + sc->enif.if_unit = unit; + sc->enif.if_name = "en"; + /* figure out if we are an adaptec card or not */ + sc->is_adaptec = (pci_get_vendor(dev) == PCI_VENDOR_ADP) ? 1 : 0; + /* * set up pci bridge */ - #if !defined(MIDWAY_ENIONLY) if (sc->is_adaptec) { adp_get_macaddr(scp); @@ -292,9 +278,9 @@ #if !defined(MIDWAY_ADPONLY) if (!sc->is_adaptec) { - eni_get_macaddr(scp); + eni_get_macaddr(dev, scp); sc->en_busreset = NULL; - pci_conf_write(config_id, EN_TONGA, (TONGA_SWAP_DMA|TONGA_SWAP_WORD)); + pci_write_config(dev, EN_TONGA, (TONGA_SWAP_DMA|TONGA_SWAP_WORD), 4); } #endif @@ -304,26 +290,64 @@ en_attach(sc); + splx(s); + + return 0; + + fail: + splx(s); + return error; +} + +static int +en_pci_detach(device_t dev) +{ + struct en_softc *sc = device_get_softc(dev); + struct en_pci_softc *scp = (struct en_pci_softc *)sc; + int s; + + s = splimp(); + + /* + * Close down routes etc. + */ + if_detach(&sc->enif); + + /* + * Stop DMA and drop transmit queue. + */ + en_reset(sc); + + /* + * Deallocate resources. + */ + bus_teardown_intr(dev, scp->irq, scp->ih); + bus_release_resource(dev, SYS_RES_IRQ, 0, scp->irq); + bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, scp->res); + +#ifdef notyet + /* + * Free all the driver internal resources + */ +#endif + + splx(s); + + return 0; } -static void -en_pci_shutdown( - void *sc, - int howto) +static int +en_pci_shutdown(device_t dev) { - struct en_pci_softc *psc = (struct en_pci_softc *)sc; + struct en_pci_softc *psc = (struct en_pci_softc *)device_get_softc(dev); en_reset(&psc->esc); - DELAY(10); + DELAY(10); /* is this necessary? -kjc */ + return (0); } #if !defined(MIDWAY_ENIONLY) -#if defined(sparc) || defined(__FreeBSD__) -#define bus_space_read_1(t, h, o) \ - ((void)t, (*(volatile u_int8_t *)((h) + (o)))) -#endif - static void adp_get_macaddr(scp) struct en_pci_softc *scp; @@ -332,8 +356,8 @@ int lcv; for (lcv = 0; lcv < sizeof(sc->macaddr); lcv++) - sc->macaddr[lcv] = bus_space_read_1(sc->en_memt, sc->en_base, - MID_ADPMACOFF + lcv); + sc->macaddr[lcv] = bus_space_read_1(sc->en_memt, sc->en_base, + MID_ADPMACOFF + lcv); } #endif /* MIDWAY_ENIONLY */ @@ -350,90 +374,109 @@ #define EN_ESI 64 static void -eni_get_macaddr(scp) - struct en_pci_softc *scp; +eni_get_macaddr(device_t dev, struct en_pci_softc *scp) { struct en_softc * sc = (struct en_softc *)scp; - pcici_t id = scp->en_confid; int i, j, address, status; u_int32_t data, t_data; u_int8_t tmp; - t_data = pci_conf_read(id, EN_TONGA) & 0xffffff00; + t_data = pci_read_config(dev, EN_TONGA, 4) & 0xffffff00; data = EN_PROM_MAGIC | EN_PROM_DATA | EN_PROM_CLK; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); for (i = 0; i < sizeof(sc->macaddr); i ++){ /* start operation */ data |= EN_PROM_DATA ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data |= EN_PROM_CLK ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data &= ~EN_PROM_DATA ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data &= ~EN_PROM_CLK ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); /* send address with serial line */ address = ((i + EN_ESI) << 1) + 1; for ( j = 7 ; j >= 0 ; j --){ data = (address >> j) & 1 ? data | EN_PROM_DATA : data & ~EN_PROM_DATA; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data |= EN_PROM_CLK ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data &= ~EN_PROM_CLK ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); } /* get ack */ data |= EN_PROM_DATA ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data |= EN_PROM_CLK ; - pci_conf_write(id, EN_TONGA, data); - data = pci_conf_read(id, EN_TONGA); + pci_write_config(dev, EN_TONGA, data, 4); + data = pci_read_config(dev, EN_TONGA, 4); status = data & EN_PROM_DATA; data &= ~EN_PROM_CLK ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data |= EN_PROM_DATA ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); tmp = 0; for ( j = 7 ; j >= 0 ; j --){ tmp <<= 1; data |= EN_PROM_DATA ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data |= EN_PROM_CLK ; - pci_conf_write(id, EN_TONGA, data); - data = pci_conf_read(id, EN_TONGA); + pci_write_config(dev, EN_TONGA, data, 4); + data = pci_read_config(dev, EN_TONGA, 4); if(data & EN_PROM_DATA) tmp |= 1; data &= ~EN_PROM_CLK ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data |= EN_PROM_DATA ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); } /* get ack */ data |= EN_PROM_DATA ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data |= EN_PROM_CLK ; - pci_conf_write(id, EN_TONGA, data); - data = pci_conf_read(id, EN_TONGA); + pci_write_config(dev, EN_TONGA, data, 4); + data = pci_read_config(dev, EN_TONGA, 4); status = data & EN_PROM_DATA; data &= ~EN_PROM_CLK ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data |= EN_PROM_DATA ; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); sc->macaddr[i] = tmp; } /* stop operation */ data &= ~EN_PROM_DATA; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data |= EN_PROM_CLK; - pci_conf_write(id, EN_TONGA, data); + pci_write_config(dev, EN_TONGA, data, 4); data |= EN_PROM_DATA; - pci_conf_write(id, EN_TONGA, data); - pci_conf_write(id, EN_TONGA, t_data); + pci_write_config(dev, EN_TONGA, data, 4); + pci_write_config(dev, EN_TONGA, t_data, 4); } #endif /* !MIDWAY_ADPONLY */ + +static device_method_t en_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, en_pci_probe), + DEVMETHOD(device_attach, en_pci_attach), + DEVMETHOD(device_detach, en_pci_detach), + DEVMETHOD(device_shutdown, en_pci_shutdown), + + { 0, 0 } +}; + +static driver_t en_driver = { + "en", + en_methods, + sizeof(struct en_pci_softc), +}; + +static devclass_t en_devclass; + +DRIVER_MODULE(if_en, pci, en_driver, en_devclass, 0, 0); + diff -urN ../sys/pci/if_pcn.c ./pci/if_pcn.c --- ../sys/pci/if_pcn.c Thu Mar 6 03:42:33 2003 +++ ./pci/if_pcn.c Thu Apr 17 22:36:01 2003 @@ -631,7 +631,8 @@ ifp->if_watchdog = pcn_watchdog; ifp->if_init = pcn_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = PCN_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, PCN_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); /* * Do MII setup. @@ -928,7 +929,7 @@ if (mii->mii_media_status & IFM_ACTIVE && IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) sc->pcn_link++; - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) pcn_start(ifp); } @@ -972,7 +973,7 @@ } } - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) pcn_start(ifp); return; @@ -1055,16 +1056,17 @@ return; while(sc->pcn_cdata.pcn_tx_chain[idx] == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; if (pcn_encap(sc, m_head, &idx)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } + IFQ_DEQUEUE(&ifp->if_snd, m_head); + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -1073,6 +1075,8 @@ bpf_mtap(ifp, m_head); } + if (idx == sc->pcn_cdata.pcn_tx_prod) + return; /* Transmit */ sc->pcn_cdata.pcn_tx_prod = idx; @@ -1345,7 +1349,7 @@ pcn_reset(sc); pcn_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) pcn_start(ifp); return; diff -urN ../sys/pci/if_rl.c ./pci/if_rl.c --- ../sys/pci/if_rl.c Thu Mar 6 03:42:33 2003 +++ ./pci/if_rl.c Thu Apr 17 22:36:01 2003 @@ -974,7 +974,8 @@ ifp->if_watchdog = rl_watchdog; ifp->if_init = rl_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); /* * Call MI attach routine. @@ -1287,7 +1288,7 @@ sc->rxcycles = count; rl_rxeof(sc); rl_txeof(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) rl_start(ifp); if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */ @@ -1357,7 +1358,7 @@ } } - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) rl_start(ifp); return; @@ -1423,20 +1424,24 @@ { struct rl_softc *sc; struct mbuf *m_head = NULL; + int pkts = 0; sc = ifp->if_softc; while(RL_CUR_TXMBUF(sc) == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; if (rl_encap(sc, m_head)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } + /* now we are committed to transmit the packet */ + IFQ_DEQUEUE(&ifp->if_snd, m_head); + pkts++; + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -1455,6 +1460,8 @@ RL_INC(sc->rl_cdata.cur_tx); } + if (pkts == 0) + return; /* * We broke out of the loop because all our TX slots are diff -urN ../sys/pci/if_sf.c ./pci/if_sf.c --- ../sys/pci/if_sf.c Mon Dec 17 00:46:07 2001 +++ ./pci/if_sf.c Thu Apr 17 22:36:01 2003 @@ -825,7 +825,8 @@ ifp->if_watchdog = sf_watchdog; ifp->if_init = sf_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = SF_TX_DLIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, SF_TX_DLIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); /* * Call MI attach routine. @@ -1147,7 +1148,7 @@ /* Re-enable interrupts. */ csr_write_4(sc, SF_IMR, SF_INTRS); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) sf_start(ifp); return; @@ -1363,18 +1364,19 @@ cur_tx = NULL; break; } - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; cur_tx = &sc->sf_ldata->sf_tx_dlist[i]; if (sf_encap(sc, cur_tx, m_head)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; cur_tx = NULL; break; } + /* now we are committed to transmit the packet */ + IFQ_DEQUEUE(&ifp->if_snd, m_head); /* * If there's a BPF listener, bounce a copy of this frame @@ -1488,7 +1490,8 @@ if (mii->mii_media_status & IFM_ACTIVE && IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) sc->sf_link++; - if (ifp->if_snd.ifq_head != NULL) + /* XXX strange indentation. bug?? */ + if (!IFQ_IS_EMPTY(&ifp->if_snd)) sf_start(ifp); } @@ -1513,7 +1516,7 @@ sf_reset(sc); sf_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) sf_start(ifp); return; diff -urN ../sys/pci/if_sis.c ./pci/if_sis.c --- ../sys/pci/if_sis.c Thu Mar 6 03:42:33 2003 +++ ./pci/if_sis.c Thu Apr 17 22:36:01 2003 @@ -1227,7 +1227,8 @@ ifp->if_watchdog = sis_watchdog; ifp->if_init = sis_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = SIS_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, SIS_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); /* * Do MII setup. @@ -1548,7 +1549,7 @@ if (mii->mii_media_status & IFM_ACTIVE && IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) sc->sis_link++; - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) sis_start(ifp); } @@ -1664,7 +1665,7 @@ /* Re-enable interrupts. */ CSR_WRITE_4(sc, SIS_IER, 1); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) sis_start(ifp); return; @@ -1744,16 +1745,18 @@ return; while(sc->sis_ldata->sis_tx_list[idx].sis_mbuf == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; if (sis_encap(sc, m_head, &idx)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } + /* now we are committed to transmit the packet */ + IFQ_DEQUEUE(&ifp->if_snd, m_head); + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -1762,6 +1765,8 @@ bpf_mtap(ifp, m_head); } + if (idx == sc->sis_cdata.sis_tx_prod) + return; /* Transmit */ sc->sis_cdata.sis_tx_prod = idx; @@ -2062,7 +2067,7 @@ sis_reset(sc); sis_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) sis_start(ifp); return; diff -urN ../sys/pci/if_sk.c ./pci/if_sk.c --- ../sys/pci/if_sk.c Thu Mar 6 03:42:34 2003 +++ ./pci/if_sk.c Thu Apr 17 22:36:01 2003 @@ -1203,7 +1203,8 @@ ifp->if_watchdog = sk_watchdog; ifp->if_init = sk_init; ifp->if_baudrate = 1000000000; - ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, SK_TX_RING_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); /* * Do miibus setup. @@ -1528,7 +1529,7 @@ idx = sc_if->sk_cdata.sk_tx_prod; while(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -1538,11 +1539,12 @@ * for the NIC to drain the ring. */ if (sk_encap(sc_if, m_head, &idx)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } + IFQ_DEQUEUE(&ifp->if_snd, m_head); + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -1550,6 +1552,8 @@ if (ifp->if_bpf) bpf_mtap(ifp, m_head); } + if (idx == sc_if->sk_cdata.sk_tx_prod) + return; /* Transmit */ sc_if->sk_cdata.sk_tx_prod = idx; @@ -1906,9 +1910,9 @@ CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); - if (ifp0 != NULL && ifp0->if_snd.ifq_head != NULL) + if (ifp0 != NULL && !IFQ_IS_EMPTY(&ifp0->if_snd)) sk_start(ifp0); - if (ifp1 != NULL && ifp1->if_snd.ifq_head != NULL) + if (ifp1 != NULL && !IFQ_IS_EMPTY(&ifp1->if_snd)) sk_start(ifp1); return; diff -urN ../sys/pci/if_ste.c ./pci/if_ste.c --- ../sys/pci/if_ste.c Thu Feb 6 07:03:57 2003 +++ ./pci/if_ste.c Thu Apr 17 22:36:01 2003 @@ -669,7 +669,7 @@ /* Re-enable interrupts */ CSR_WRITE_2(sc, STE_IMR, STE_INTRS); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) ste_start(ifp); return; @@ -860,7 +860,7 @@ * otherwise we get stuck in the wrong link state */ ste_miibus_statchg(sc->ste_dev); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) ste_start(ifp); } } @@ -1075,7 +1075,8 @@ ifp->if_watchdog = ste_watchdog; ifp->if_init = ste_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = STE_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, STE_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); sc->ste_tx_thresh = STE_TXSTART_THRESH; @@ -1560,7 +1561,7 @@ break; } - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -1626,7 +1627,7 @@ ste_reset(sc); ste_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) ste_start(ifp); return; diff -urN ../sys/pci/if_ti.c ./pci/if_ti.c --- ../sys/pci/if_ti.c Fri Feb 15 13:20:20 2002 +++ ./pci/if_ti.c Thu Apr 17 22:36:01 2003 @@ -1722,7 +1722,8 @@ ifp->if_watchdog = ti_watchdog; ifp->if_init = ti_init; ifp->if_mtu = ETHERMTU; - ifp->if_snd.ifq_maxlen = TI_TX_RING_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, TI_TX_RING_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); /* Set up ifmedia support. */ ifmedia_init(&sc->ifmedia, IFM_IMASK, ti_ifmedia_upd, ti_ifmedia_sts); @@ -1994,7 +1995,7 @@ /* Re-enable interrupts. */ CSR_WRITE_4(sc, TI_MB_HOSTINTR, 0); - if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) + if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd)) ti_start(ifp); return; @@ -2127,13 +2128,14 @@ struct ti_softc *sc; struct mbuf *m_head = NULL; u_int32_t prodidx = 0; + int pkts = 0; sc = ifp->if_softc; prodidx = CSR_READ_4(sc, TI_MB_SENDPROD_IDX); while(sc->ti_cdata.ti_tx_chain[prodidx] == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -2149,7 +2151,6 @@ m_head->m_pkthdr.csum_flags & (CSUM_DELAY_DATA)) { if ((TI_TX_RING_CNT - sc->ti_txcnt) < m_head->m_pkthdr.csum_data + 16) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } @@ -2161,11 +2162,14 @@ * for the NIC to drain the ring. */ if (ti_encap(sc, m_head, &prodidx)) { - IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; break; } + /* now we are committed to transmit the packet */ + IFQ_DEQUEUE(&ifp->if_snd, m_head); + pkts++; + /* * If there's a BPF listener, bounce a copy of this frame * to him. @@ -2173,6 +2177,8 @@ if (ifp->if_bpf) bpf_mtap(ifp, m_head); } + if (pkts == 0) + return; /* Transmit */ CSR_WRITE_4(sc, TI_MB_SENDPROD_IDX, prodidx); diff -urN ../sys/pci/if_tl.c ./pci/if_tl.c --- ../sys/pci/if_tl.c Mon Dec 17 00:46:08 2001 +++ ./pci/if_tl.c Thu Apr 17 22:36:01 2003 @@ -1302,7 +1302,8 @@ ifp->if_watchdog = tl_watchdog; ifp->if_init = tl_init; ifp->if_mtu = ETHERMTU; - ifp->if_snd.ifq_maxlen = TL_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, TL_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); callout_handle_init(&sc->tl_stat_ch); /* Reset the adapter again. */ @@ -1770,7 +1771,7 @@ CMD_PUT(sc, TL_CMD_ACK | r | type); } - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) tl_start(ifp); return; @@ -1959,7 +1960,7 @@ start_tx = sc->tl_cdata.tl_tx_free; while(sc->tl_cdata.tl_tx_free != NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; diff -urN ../sys/pci/if_vr.c ./pci/if_vr.c --- ../sys/pci/if_vr.c Thu Feb 6 13:46:20 2003 +++ ./pci/if_vr.c Thu Apr 17 22:36:53 2003 @@ -886,7 +886,8 @@ ifp->if_watchdog = vr_watchdog; ifp->if_init = vr_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = VR_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, VR_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); /* * Do MII setup. @@ -1372,7 +1373,7 @@ /* Re-enable interrupts. */ CSR_WRITE_2(sc, VR_IMR, VR_INTRS); - if (ifp->if_snd.ifq_head != NULL) { + if (!IFQ_IS_EMPTY(&ifp->if_snd)) { vr_start(ifp); } @@ -1479,7 +1480,7 @@ start_tx = sc->vr_cdata.vr_tx_free; while(sc->vr_cdata.vr_tx_free->vr_mbuf == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -1489,8 +1490,12 @@ /* Pack the data into the descriptor. */ if (vr_encap(sc, cur_tx, m_head)) { - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_flags |= IFF_OACTIVE; + if (ALTQ_IS_ENABLED(&ifp->if_snd)) { + m_freem(m_head); + } else { + IF_PREPEND(&ifp->if_snd, m_head); + ifp->if_flags |= IFF_OACTIVE; + } cur_tx = NULL; break; } @@ -1729,7 +1734,7 @@ vr_reset(sc); vr_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) vr_start(ifp); return; diff -urN ../sys/pci/if_wb.c ./pci/if_wb.c --- ../sys/pci/if_wb.c Thu Mar 6 03:42:34 2003 +++ ./pci/if_wb.c Thu Apr 17 22:36:53 2003 @@ -949,7 +949,8 @@ ifp->if_watchdog = wb_watchdog; ifp->if_init = wb_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = WB_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, WB_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); /* * Do MII setup. @@ -1371,7 +1372,7 @@ /* Re-enable interrupts. */ CSR_WRITE_4(sc, WB_IMR, WB_INTRS); - if (ifp->if_snd.ifq_head != NULL) { + if (!IFQ_IS_EMPTY(&ifp->if_snd)) { wb_start(ifp); } @@ -1518,7 +1519,7 @@ start_tx = sc->wb_cdata.wb_tx_free; while(sc->wb_cdata.wb_tx_free->wb_mbuf == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -1807,7 +1808,7 @@ wb_reset(sc); wb_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) wb_start(ifp); return; diff -urN ../sys/pci/if_wx.c ./pci/if_wx.c --- ../sys/pci/if_wx.c Thu Mar 6 03:42:34 2003 +++ ./pci/if_wx.c Thu Apr 17 22:36:53 2003 @@ -345,7 +345,8 @@ ifp->if_ioctl = wx_ioctl; ifp->if_start = wx_start; ifp->if_watchdog = wx_txwatchdog; - ifp->if_snd.ifq_maxlen = WX_MAX_TDESC - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, WX_MAX_TDESC - 1); + IFQ_SET_READY(&ifp->if_snd); ether_ifattach(ifp, ETHER_BPF_SUPPORTED); out: WX_UNLOCK(sc); @@ -755,7 +756,7 @@ int gctried = 0; struct mbuf *m, *mb_head; - IF_DEQUEUE(&ifp->if_snd, mb_head); + IFQ_DEQUEUE(&ifp->if_snd, mb_head); if (mb_head == NULL) { break; } @@ -926,6 +927,17 @@ if (nactv == WX_MAX_TDESC && mb_head->m_next == NULL) { sc->wx_xmitputback++; ifp->if_flags |= IFF_OACTIVE; +#ifdef ALTQ + /* + * XXX when altq is enabled, we can't put the + * packet back to the queue. + * just give up this packet for now. + */ + if (ALTQ_IS_ENABLED(&ifp->if_snd)) { + m_freem(mb_head); + break; + } +#endif IF_PREPEND(&ifp->if_snd, mb_head); break; } @@ -1018,7 +1030,7 @@ wx_gc(sc); } #endif - if (sc->wx_if.if_snd.ifq_head != NULL) { + if (IFQ_IS_EMPTY(&sc->wx_if.if_snd) == 0) { wx_start(&sc->wx_if); } WX_ENABLE_INT(sc); diff -urN ../sys/pci/if_xl.c ./pci/if_xl.c --- ../sys/pci/if_xl.c Thu Feb 6 07:03:58 2003 +++ ./pci/if_xl.c Thu Apr 17 22:36:53 2003 @@ -897,6 +897,7 @@ { struct mbuf *m; struct ifnet *ifp; + int error; ifp = &sc->arpcom.ac_if; @@ -914,7 +915,7 @@ mtod(m, unsigned char *)[15] = 0; mtod(m, unsigned char *)[16] = 0xE3; m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3; - IF_ENQUEUE(&ifp->if_snd, m); + IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error); xl_start(ifp); return; @@ -1503,7 +1504,8 @@ ifp->if_watchdog = xl_watchdog; ifp->if_init = xl_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = XL_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, XL_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); ifp->if_capenable = ifp->if_capabilities; /* @@ -2184,7 +2186,7 @@ } } - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) (*ifp->if_start)(ifp); return; @@ -2365,7 +2367,7 @@ start_tx = sc->xl_cdata.xl_tx_free; while(sc->xl_cdata.xl_tx_free != NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -2481,7 +2483,7 @@ break; } - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -2947,7 +2949,7 @@ xl_reset(sc); xl_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) (*ifp->if_start)(ifp); return;