Date: Wed, 15 Oct 2003 09:58:35 -0700 (PDT) From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 39751 for review Message-ID: <200310151658.h9FGwZAj087116@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=39751 Change 39751 by sam@sam_ebb on 2003/10/15 09:58:00 IFC Affected files ... .. //depot/projects/netperf/sys/amd64/amd64/exception.S#4 integrate .. //depot/projects/netperf/sys/amd64/amd64/trap.c#5 integrate .. //depot/projects/netperf/sys/amd64/include/frame.h#2 integrate .. //depot/projects/netperf/sys/amd64/include/signal.h#3 integrate .. //depot/projects/netperf/sys/amd64/include/ucontext.h#4 integrate .. //depot/projects/netperf/sys/conf/files#13 integrate .. //depot/projects/netperf/sys/dev/ata/ata-queue.c#6 integrate .. //depot/projects/netperf/sys/dev/ath/if_ath.c#21 integrate .. //depot/projects/netperf/sys/dev/ath/if_ath_pci.c#5 integrate .. //depot/projects/netperf/sys/dev/ath/if_athvar.h#6 integrate .. //depot/projects/netperf/sys/dev/em/if_em.c#8 integrate .. //depot/projects/netperf/sys/dev/xe/if_xe.c#3 integrate .. //depot/projects/netperf/sys/dev/xe/if_xe_pccard.c#4 integrate .. //depot/projects/netperf/sys/dev/xe/if_xereg.h#2 integrate .. //depot/projects/netperf/sys/dev/xe/if_xevar.h#2 integrate .. //depot/projects/netperf/sys/i386/i386/locore.s#7 edit .. //depot/projects/netperf/sys/i386/i386/pmap.c#18 integrate .. //depot/projects/netperf/sys/kern/kern_poll.c#5 integrate .. //depot/projects/netperf/sys/kern/kern_proc.c#5 integrate .. //depot/projects/netperf/sys/kern/sched_ule.c#8 integrate .. //depot/projects/netperf/sys/netinet/in_rmx.c#7 integrate .. //depot/projects/netperf/sys/netinet/ip_input.c#11 integrate .. //depot/projects/netperf/sys/netinet/ip_var.h#7 integrate .. //depot/projects/netperf/sys/netinet6/nd6.c#10 integrate .. //depot/projects/netperf/sys/vm/vm_fault.c#7 integrate Differences ... ==== //depot/projects/netperf/sys/amd64/amd64/exception.S#4 (text+ko) ==== @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/amd64/amd64/exception.S,v 1.112 2003/09/22 22:54:14 peter Exp $ + * $FreeBSD: src/sys/amd64/amd64/exception.S,v 1.113 2003/10/15 02:04:52 peter Exp $ */ #include <machine/asmacros.h> @@ -228,7 +228,7 @@ movq %rsp,PCPU(SCRATCH_RSP) movq common_tss+COMMON_TSS_RSP0,%rsp /* Now emulate a trapframe. Make the 8 byte alignment odd for call. */ - subq $TF_SIZE+8,%rsp + subq $TF_SIZE,%rsp /* defer TF_RSP till we have a spare register */ movq %r11,TF_RFLAGS(%rsp) movq %rcx,TF_RIP(%rsp) /* %rcx original value is in %r10 */ ==== //depot/projects/netperf/sys/amd64/amd64/trap.c#5 (text+ko) ==== @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/amd64/trap.c,v 1.265 2003/10/09 10:17:16 robert Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/trap.c,v 1.266 2003/10/15 02:04:52 peter Exp $"); /* * AMD64 Trap and System call handling @@ -258,6 +258,9 @@ default: ucode = code + BUS_SEGM_FAULT ; i = SIGBUS; +printf("trap %d: pid %d err %p eva %p, rip %p, rax %p, rbx %p, rcx %p, rdx %p, rsp %p, rbp %p, rsi %p, rdi %p\n", type, p->p_pid, (void *)frame.tf_err, +(void *)frame.tf_addr, (void *)frame.tf_rip, (void *)frame.tf_rax, (void *)frame.tf_rbx, (void *)frame.tf_rcx, (void *)frame.tf_rdx, (void *)frame.tf_rsp, (void *)frame.tf_rbp, (void *)frame.tf_rsi, (void *)frame.tf_rdi); + break; case T_PAGEFLT: /* page fault */ @@ -542,6 +545,12 @@ return (-1); } +printf("trap_pfault: pid %d %s %s %s eva %p, rip %p, rax %p, rbx %p, rcx %p, rdx %p, rsp %p, rbp %p, rsi %p, rdi %p\n", p->p_pid, + frame->tf_err & PGEX_U ? "user" : "supervisor", + frame->tf_err & PGEX_W ? "write" : "read", + frame->tf_err & PGEX_P ? "protection violation" : "page not present", +(void *)eva, (void *)frame->tf_rip, (void *)frame->tf_rax, (void *)frame->tf_rbx, (void *)frame->tf_rcx, (void *)frame->tf_rdx, (void *)frame->tf_rsp, (void *)frame->tf_rbp, (void *)frame->tf_rsi, (void *)frame->tf_rdi); + return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); } ==== //depot/projects/netperf/sys/amd64/include/frame.h#2 (text+ko) ==== @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)frame.h 5.2 (Berkeley) 1/18/91 - * $FreeBSD: src/sys/amd64/include/frame.h,v 1.24 2003/05/12 18:33:19 peter Exp $ + * $FreeBSD: src/sys/amd64/include/frame.h,v 1.25 2003/10/15 02:04:52 peter Exp $ */ #ifndef _MACHINE_FRAME_H_ @@ -69,6 +69,7 @@ register_t tf_r15; register_t tf_trapno; register_t tf_addr; + register_t tf_flags; /* below portion defined in hardware */ register_t tf_err; register_t tf_rip; @@ -98,6 +99,7 @@ register_t if_r15; register_t :64; /* compat with trap frame - trapno */ register_t :64; /* compat with trap frame - addr */ + register_t :64; /* compat with trap frame - flags */ register_t :64; /* compat with trap frame - err */ /* below portion defined in hardware */ register_t if_rip; @@ -127,6 +129,7 @@ register_t cf_r15; register_t :64; /* compat with trap frame - trapno */ register_t :64; /* compat with trap frame - addr */ + register_t :64; /* compat with trap frame - flags */ register_t :64; /* compat with trap frame - err */ /* below portion defined in hardware */ register_t cf_rip; ==== //depot/projects/netperf/sys/amd64/include/signal.h#3 (text+ko) ==== @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)signal.h 8.1 (Berkeley) 6/11/93 - * $FreeBSD: src/sys/amd64/include/signal.h,v 1.23 2003/09/08 18:31:48 peter Exp $ + * $FreeBSD: src/sys/amd64/include/signal.h,v 1.24 2003/10/15 02:04:52 peter Exp $ */ #ifndef _MACHINE_SIGNAL_H_ @@ -91,6 +91,7 @@ long sc_r15; long sc_trapno; long sc_addr; + long sc_flags; long sc_err; long sc_rip; long sc_cs; @@ -104,9 +105,8 @@ */ long sc_fpformat; long sc_ownedfp; - long sc_spare1[1]; long sc_fpstate[64] __aligned(16); - long sc_spare2[8]; + long sc_spare[8]; }; #endif /* __BSD_VISIBLE */ ==== //depot/projects/netperf/sys/amd64/include/ucontext.h#4 (text+ko) ==== @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/amd64/include/ucontext.h,v 1.15 2003/10/01 01:08:04 peter Exp $ + * $FreeBSD: src/sys/amd64/include/ucontext.h,v 1.16 2003/10/15 02:04:52 peter Exp $ */ #ifndef _MACHINE_UCONTEXT_H_ @@ -55,6 +55,7 @@ __register_t mc_r15; __register_t mc_trapno; __register_t mc_addr; + __register_t mc_flags; __register_t mc_err; __register_t mc_rip; __register_t mc_cs; @@ -70,12 +71,11 @@ #define _MC_FPOWNED_FPU 0x20001 /* FP state came from FPU */ #define _MC_FPOWNED_PCB 0x20002 /* FP state came from PCB */ long mc_ownedfp; - long mc_spare1[1]; /* align mc_fpstate to 16 bytes */ /* * See <machine/npx.h> for the internals of mc_fpstate[]. */ long mc_fpstate[64] __aligned(16); - long mc_spare2[8]; + long mc_spare[8]; } mcontext_t; #endif /* !_MACHINE_UCONTEXT_H_ */ ==== //depot/projects/netperf/sys/conf/files#13 (text+ko) ==== @@ -1,4 +1,4 @@ -# $FreeBSD: src/sys/conf/files,v 1.833 2003/10/13 19:26:07 ume Exp $ +# $FreeBSD: src/sys/conf/files,v 1.834 2003/10/15 08:53:04 phk Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -949,6 +949,9 @@ geom/bde/g_bde_crypt.c optional geom_bde geom/bde/g_bde_lock.c optional geom_bde geom/bde/g_bde_work.c optional geom_bde +crypto/rijndael/rijndael-alg-fst.c optional geom_bde +crypto/rijndael/rijndael-api-fst.c optional geom_bde +crypto/sha2/sha2.c optional geom_bde geom/geom_aes.c optional geom_aes geom/geom_apple.c optional geom_apple geom/geom_bsd.c optional geom_bsd @@ -974,8 +977,6 @@ geom/geom_sunlabel.c optional geom_sunlabel geom/geom_sunlabel_enc.c optional geom_sunlabel geom/geom_vol_ffs.c optional geom_vol -crypto/rijndael/rijndael-alg-fst.c optional geom -crypto/rijndael/rijndael-api-fst.c optional geom gnu/ext2fs/ext2_alloc.c optional ext2fs \ warning "kernel contains GPL contaminated ext2fs filesystem" gnu/ext2fs/ext2_balloc.c optional ext2fs ==== //depot/projects/netperf/sys/dev/ata/ata-queue.c#6 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/ata/ata-queue.c,v 1.8 2003/10/12 12:38:03 sos Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/ata-queue.c,v 1.9 2003/10/14 16:53:13 sos Exp $"); #include "opt_ata.h" #include <sys/param.h> @@ -315,20 +315,21 @@ static void ata_timeout(struct ata_request *request) { + struct ata_channel *ch = request->device->channel; + int quiet = request->flags & ATA_R_QUIET; + /* clear timeout etc */ request->timeout_handle.callout = NULL; -#if 0 - /* call interrupt to try finish up the command */ - request->device->channel->hw.interrupt(request->device->channel); - if (request->device->channel->running == NULL) { - if (!(request->flags & ATA_R_QUIET)) + /* call hw.interrupt to try finish up the command */ + ch->hw.interrupt(request->device->channel); + if (ch->running != request) { + if (!quiet) ata_prtdev(request->device, "WARNING - %s recovered from missing interrupt\n", ata_cmd2str(request)); return; } -#endif /* if this was a DMA request stop the engine to be on the safe side */ if (request->flags & ATA_R_DMA) { ==== //depot/projects/netperf/sys/dev/ath/if_ath.c#21 (text+ko) ==== @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.24 2003/10/13 04:57:31 sam Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.25 2003/10/14 22:51:45 sam Exp $"); /* * Driver for the Atheros Wireless LAN controller. ==== //depot/projects/netperf/sys/dev/ath/if_ath_pci.c#5 (text+ko) ==== @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath_pci.c,v 1.3 2003/08/13 21:29:35 sam Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath_pci.c,v 1.4 2003/10/14 22:51:45 sam Exp $"); /* * PCI/Cardbus front-end for the Atheros Wireless LAN controller driver. ==== //depot/projects/netperf/sys/dev/ath/if_athvar.h#6 (text+ko) ==== @@ -33,7 +33,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * - * $FreeBSD: src/sys/dev/ath/if_athvar.h,v 1.8 2003/09/15 22:34:46 sam Exp $ + * $FreeBSD: src/sys/dev/ath/if_athvar.h,v 1.9 2003/10/14 22:51:45 sam Exp $ */ /* ==== //depot/projects/netperf/sys/dev/em/if_em.c#8 (text+ko) ==== @@ -31,7 +31,7 @@ ***************************************************************************/ -/*$FreeBSD: src/sys/dev/em/if_em.c,v 1.31 2003/10/10 23:14:20 sam Exp $*/ +/*$FreeBSD: src/sys/dev/em/if_em.c,v 1.32 2003/10/15 05:34:41 deischen Exp $*/ #include <dev/em/if_em.h> @@ -167,6 +167,7 @@ static void em_82547_update_fifo_head(struct adapter *, int); static int em_82547_tx_fifo_reset(struct adapter *); static void em_82547_move_tail(void *arg); +static void em_82547_move_tail_locked(struct adapter *); static int em_dma_malloc(struct adapter *, bus_size_t, struct em_dma_alloc *, int); static void em_dma_free(struct adapter *, struct em_dma_alloc *); @@ -1284,7 +1285,7 @@ */ if (adapter->hw.mac_type == em_82547 && adapter->link_duplex == HALF_DUPLEX) { - em_82547_move_tail(adapter); + em_82547_move_tail_locked(adapter); } else { E1000_WRITE_REG(&adapter->hw, TDT, i); if (adapter->hw.mac_type == em_82547) { @@ -1304,9 +1305,8 @@ * **********************************************************************/ static void -em_82547_move_tail(void *arg) +em_82547_move_tail_locked(struct adapter *adapter) { - struct adapter *adapter = arg; uint16_t hw_tdt; uint16_t sw_tdt; struct em_tx_desc *tx_desc; @@ -1340,6 +1340,16 @@ return; } +static void +em_82547_move_tail(void *arg) +{ + struct adapter *adapter = arg; + + EM_LOCK(adapter); + em_82547_move_tail_locked(adapter); + EM_UNLOCK(adapter); +} + static int em_82547_fifo_workaround(struct adapter *adapter, int len) { ==== //depot/projects/netperf/sys/dev/xe/if_xe.c#3 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998, 1999 Scott Mitchell + * Copyright (c) 1998, 1999, 2003 Scott Mitchell * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,16 +27,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/xe/if_xe.c,v 1.38 2003/08/24 17:55:58 obrien Exp $"); - -/* - * XXX TODO XXX - * - * I've pushed this fairly far, but there are some things that need to be - * done here. I'm documenting them here in case I get destracted. -- imp - * - * xe_cem56fix -- need to figure out how to map the extra stuff. - */ +__FBSDID("$FreeBSD: src/sys/dev/xe/if_xe.c,v 1.39 2003/10/14 22:51:35 rsm Exp $"); /* * Portions of this software were derived from Werner Koch's xirc2ps driver @@ -99,14 +90,8 @@ * the CEM56/REM56 support code; and the FreeBSD UK Users' Group for hosting * the web pages. * - * Contact points: - * + * Author email: <scott@uk.freebsd.org> * Driver web page: http://ukug.uk.freebsd.org/~scott/xe_drv/ - * - * Mailing list: http://www.lovett.com/lists/freebsd-xircom/ - * or send "subscribe freebsd-xircom" to <majordomo@lovett.com> - * - * Author email: <scott@uk.freebsd.org> */ @@ -159,6 +144,10 @@ #define XE_AUTONEG_100TX 3 /* Trying to force 100baseTX link */ #define XE_AUTONEG_FAIL 4 /* Autonegotiation failed */ +/* + * Multicast hashing CRC constants + */ +#define XE_CRC_POLY 0x04c11db6 /* * Prototypes start here @@ -170,16 +159,14 @@ static int xe_media_change (struct ifnet *ifp); static void xe_media_status (struct ifnet *ifp, struct ifmediareq *mrp); static timeout_t xe_setmedia; -static void xe_hard_reset (struct xe_softc *scp); -static void xe_soft_reset (struct xe_softc *scp); +static void xe_reset (struct xe_softc *scp); static void xe_stop (struct xe_softc *scp); static void xe_enable_intr (struct xe_softc *scp); static void xe_disable_intr (struct xe_softc *scp); -static void xe_setmulti (struct xe_softc *scp); -static void xe_setaddrs (struct xe_softc *scp); +static void xe_set_multicast (struct xe_softc *scp); +static void xe_set_addr (struct xe_softc *scp, u_int8_t* addr, unsigned idx); +static void xe_set_hash (struct xe_softc *scp, u_int8_t* addr); static int xe_pio_write_packet (struct xe_softc *scp, struct mbuf *mbp); -static u_int32_t xe_compute_crc (u_int8_t *data, int len) __unused; -static int xe_compute_hashbit (u_int32_t crc) __unused; /* * MII functions @@ -192,12 +179,16 @@ static u_int16_t xe_phy_readreg (struct xe_softc *scp, u_int16_t reg); static void xe_phy_writereg (struct xe_softc *scp, u_int16_t reg, u_int16_t data); + /* - * Debug functions -- uncomment for VERY verbose dignostic information. - * Set to 1 for less verbose information + * Debug logging level (comment out for normal operation): + * 1 = Log more hardware details, xe_ioctl details + * 2 = Log most function calls, some (eg. multicast, MII) in detail + * 3 = Log everything, including all interrupts and packets sent */ -/* #define XE_DEBUG 2 */ -#ifdef XE_DEBUG +#define XE_DEBUG 0 + +#if XE_DEBUG > 2 #define XE_REG_DUMP(scp) xe_reg_dump((scp)) #define XE_MII_DUMP(scp) xe_mii_dump((scp)) static void xe_reg_dump (struct xe_softc *scp); @@ -207,6 +198,7 @@ #define XE_MII_DUMP(scp) #endif + /* * Attach a device. */ @@ -215,20 +207,16 @@ { struct xe_softc *scp = device_get_softc(dev); -#ifdef XE_DEBUG +#if XE_DEBUG > 1 device_printf(dev, "attach\n"); #endif - /* Fill in some private data */ + /* Initialise stuff... */ + scp->dev = dev; scp->ifp = &scp->arpcom.ac_if; scp->ifm = &scp->ifmedia; - scp->autoneg_status = 0; - - /* Hopefully safe to read this here */ - XE_SELECT_PAGE(4); - scp->version = XE_INB(XE_BOV); + scp->autoneg_status = XE_AUTONEG_NONE; - scp->dev = dev; /* Initialise the ifnet structure */ if (!scp->ifp->if_name) { scp->ifp->if_softc = scp; @@ -243,6 +231,7 @@ scp->ifp->if_ioctl = xe_ioctl; scp->ifp->if_watchdog = xe_watchdog; scp->ifp->if_init = xe_init; + scp->ifp->if_baudrate = 100000000; scp->ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; } @@ -250,44 +239,52 @@ ifmedia_init(scp->ifm, 0, xe_media_change, xe_media_status); callout_handle_init(&scp->chand); - /* - * Fill in supported media types. Some cards _do_ support full duplex - * operation, but this driver doesn't, yet. Therefore we leave those modes - * out of the list. We support some form of autoselection in all cases. - */ + /* Add supported media types */ if (scp->mohawk) { ifmedia_add(scp->ifm, IFM_ETHER|IFM_100_TX, 0, NULL); - ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T, 0, NULL); + ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); + ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL); } - else { - ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T, 0, NULL); + ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T, 0, NULL); + if (scp->ce2) ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_2, 0, NULL); - } ifmedia_add(scp->ifm, IFM_ETHER|IFM_AUTO, 0, NULL); /* Default is to autoselect best supported media type */ ifmedia_set(scp->ifm, IFM_ETHER|IFM_AUTO); + /* Get the hardware into a known state */ + xe_reset(scp); + + /* Get hardware version numbers */ + XE_SELECT_PAGE(4); + scp->version = XE_INB(XE_BOV); + if (scp->mohawk) + scp->srev = (XE_INB(XE_BOV) & 0x70) >> 4; + else + scp->srev = (XE_INB(XE_BOV) & 0x30) >> 4; + /* Print some useful information */ - device_printf(dev, "%s %s, bonding version %#x%s%s\n", + device_printf(dev, "%s %s, version 0x%02x/0x%02x%s%s\n", scp->vendor, scp->card_type, scp->version, + scp->srev, scp->mohawk ? ", 100Mbps capable" : "", scp->modem ? ", with modem" : ""); +#if XE_DEBUG > 0 if (scp->mohawk) { XE_SELECT_PAGE(0x10); - device_printf(dev, "DingoID = %#x, RevisionID = %#x, VendorID = %#x\n", + device_printf(dev, "DingoID=0x%04x, RevisionID=0x%04x, VendorID=0x%04x\n", XE_INW(XE_DINGOID), XE_INW(XE_RevID), XE_INW(XE_VendorID)); } if (scp->ce2) { XE_SELECT_PAGE(0x45); - device_printf(dev, "CE2 version = %#x\n", XE_INB(XE_REV)); + device_printf(dev, "CE2 version = 0x%#02x\n", XE_INB(XE_REV)); } - - /* Print MAC address */ +#endif device_printf(dev, "Ethernet address %6D\n", scp->arpcom.ac_enaddr, ":"); /* Attach the interface */ @@ -299,105 +296,153 @@ /* - * Initialize device. Completes the reset procedure on the card and starts - * output. If there's an autonegotiation in progress we DON'T do anything; - * the media selection code will call us again when it's done. + * Complete hardware intitialisation and enable output. Exits without doing + * anything if there's no address assigned to the card, or if media selection + * is in progress (the latter implies we've already run this function). */ static void xe_init(void *xscp) { struct xe_softc *scp = xscp; + unsigned i; int s; -#ifdef XE_DEBUG + if (TAILQ_EMPTY(&scp->ifp->if_addrhead)) return; + + if (scp->autoneg_status != XE_AUTONEG_NONE) return; + +#if XE_DEBUG > 1 device_printf(scp->dev, "init\n"); #endif - if (TAILQ_EMPTY(&scp->ifp->if_addrhead)) return; + s = splimp(); /* Reset transmitter flags */ scp->tx_queued = 0; scp->tx_tpr = 0; - scp->tx_collisions = 0; + scp->tx_timeouts = 0; + scp->tx_thres = 64; + scp->tx_min = ETHER_MIN_LEN - ETHER_CRC_LEN; scp->ifp->if_timer = 0; - s = splimp(); + /* Soft reset the card */ + XE_SELECT_PAGE(0); + XE_OUTB(XE_CR, XE_CR_SOFT_RESET); + DELAY(40000); + XE_OUTB(XE_CR, 0); + DELAY(40000); + + if (scp->mohawk) { + /* + * set GP1 and GP2 as outputs (bits 2 & 3) + * set GP1 low to power on the ML6692 (bit 0) + * set GP2 high to power on the 10Mhz chip (bit 1) + */ + XE_SELECT_PAGE(4); + XE_OUTB(XE_GPR0, XE_GPR0_GP2_SELECT|XE_GPR0_GP1_SELECT|XE_GPR0_GP2_OUT); + } + + /* Shut off interrupts */ + xe_disable_intr(scp); + + /* Wait for everything to wake up */ + DELAY(500000); + + /* Check for PHY */ + if (scp->mohawk) + scp->phy_ok = xe_mii_init(scp); + /* Disable 'source insertion' (not sure what that means) */ XE_SELECT_PAGE(0x42); - XE_OUTB(XE_SWC0, 0x20); /* Disable source insertion (WTF is that?) */ + XE_OUTB(XE_SWC0, XE_SWC0_NO_SRC_INSERT); - /* - * Set the 'local memory dividing line' -- splits the 32K card memory into - * 8K for transmit buffers and 24K for receive. This is done automatically - * on newer revision cards. - */ + /* Set 8K/24K Tx/Rx buffer split */ if (scp->srev != 1) { XE_SELECT_PAGE(2); XE_OUTW(XE_RBS, 0x2000); } + /* Enable early transmit mode on Mohawk/Dingo */ + if (scp->mohawk) { + XE_SELECT_PAGE(0x03); + XE_OUTW(XE_TPT, scp->tx_thres); + XE_SELECT_PAGE(0x01); + XE_OUTB(XE_ECR, XE_INB(XE_ECR) | XE_ECR_EARLY_TX); + } + + /* Put MAC address in first 'individual address' register */ + XE_SELECT_PAGE(0x50); + for (i = 0; i < 6; i++) + XE_OUTB(0x08 + i, scp->arpcom.ac_enaddr[scp->mohawk ? 5 - i : i]); + /* Set up multicast addresses */ - xe_setmulti(scp); + xe_set_multicast(scp); - /* Fix the data offset register -- reset leaves it off-by-one */ + /* Fix the receive data offset -- reset can leave it off-by-one */ XE_SELECT_PAGE(0); XE_OUTW(XE_DO, 0x2000); - /* - * Set MAC interrupt masks and clear status regs. The bit names are direct - * from the Linux code; I have no idea what most of them do. - */ - XE_SELECT_PAGE(0x40); /* Bit 7..0 */ - XE_OUTB(XE_RX0Msk, 0xff); /* ROK, RAB, rsv, RO, CRC, AE, PTL, MP */ - XE_OUTB(XE_TX0Msk, 0xff); /* TOK, TAB, SQE, LL, TU, JAB, EXC, CRS */ - XE_OUTB(XE_TX0Msk+1, 0xb0); /* rsv, rsv, PTD, EXT, rsv, rsv, rsv, rsv */ - XE_OUTB(XE_RST0, 0x00); /* ROK, RAB, REN, RO, CRC, AE, PTL, MP */ - XE_OUTB(XE_TXST0, 0x00); /* TOK, TAB, SQE, LL, TU, JAB, EXC, CRS */ - XE_OUTB(XE_TXST1, 0x00); /* TEN, rsv, PTD, EXT, retry_counter:4 */ + /* Set interrupt masks */ + XE_SELECT_PAGE(1); + XE_OUTB(XE_IMR0, XE_IMR0_TX_PACKET | XE_IMR0_MAC_INTR | XE_IMR0_RX_PACKET); + + /* Set MAC interrupt masks */ + XE_SELECT_PAGE(0x40); + XE_OUTB(XE_RX0Msk, + ~(XE_RX0M_RX_OVERRUN | XE_RX0M_CRC_ERROR + | XE_RX0M_ALIGN_ERROR | XE_RX0M_LONG_PACKET)); + XE_OUTB(XE_TX0Msk, + ~(XE_TX0M_SQE_FAIL | XE_TX0M_LATE_COLLISION | XE_TX0M_TX_UNDERRUN + | XE_TX0M_16_COLLISIONS | XE_TX0M_NO_CARRIER)); + + /* Clear MAC status registers */ + XE_SELECT_PAGE(0x40); + XE_OUTB(XE_RST0, 0x00); + XE_OUTB(XE_TXST0, 0x00); + + /* Enable receiver and put MAC online */ + XE_SELECT_PAGE(0x40); + XE_OUTB(XE_CMD0, XE_CMD0_RX_ENABLE|XE_CMD0_ONLINE); - /* - * Check for an in-progress autonegotiation. If one is active, just set - * IFF_RUNNING and return. The media selection code will call us again when - * it's done. - */ - if (scp->autoneg_status) { - scp->ifp->if_flags |= IFF_RUNNING; - } - else { - /* Enable receiver, put MAC online */ - XE_SELECT_PAGE(0x40); - XE_OUTB(XE_CMD0, XE_CMD0_RX_ENABLE|XE_CMD0_ONLINE); + /* Set up IMR, enable interrupts */ + xe_enable_intr(scp); - /* Set up IMR, enable interrupts */ - xe_enable_intr(scp); + /* Start media selection */ + xe_setmedia(scp); - /* Attempt to start output */ - scp->ifp->if_flags |= IFF_RUNNING; - scp->ifp->if_flags &= ~IFF_OACTIVE; - xe_start(scp->ifp); - } + /* Enable output */ + scp->ifp->if_flags |= IFF_RUNNING; + scp->ifp->if_flags &= ~IFF_OACTIVE; (void)splx(s); } /* - * Start output on interface. We make two assumptions here: - * 1) that the current priority is set to splimp _before_ this code - * is called *and* is returned to the appropriate priority after - * return - * 2) that the IFF_OACTIVE flag is checked before this code is called - * (i.e. that the output part of the interface is idle) + * Start output on interface. Should be called at splimp() priority. Check + * that the output is idle (ie, IFF_OACTIVE is not set) before calling this + * function. If media selection is in progress we set IFF_OACTIVE ourselves + * and return immediately. */ static void xe_start(struct ifnet *ifp) { struct xe_softc *scp = ifp->if_softc; struct mbuf *mbp; + if (scp->autoneg_status != XE_AUTONEG_NONE) { + ifp->if_flags |= IFF_OACTIVE; + return; + } + +#if XE_DEBUG > 2 + device_printf(scp->dev, "start\n"); +#endif + /* * 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 */ + /* Suck a packet off the send queue */ + IF_DEQUEUE(&ifp->if_snd, mbp); if (mbp == NULL) { /* @@ -412,7 +457,8 @@ } if (xe_pio_write_packet(scp, mbp) != 0) { - IF_PREPEND(&ifp->if_snd, mbp); /* Push the packet back onto the queue */ + /* Push the packet back onto the queue */ + IF_PREPEND(&ifp->if_snd, mbp); ifp->if_flags |= IFF_OACTIVE; return; } @@ -420,7 +466,8 @@ /* Tap off here if there is a bpf listener */ BPF_MTAP(ifp, mbp); - ifp->if_timer = 5; /* In case we don't hear from the card again */ + /* In case we don't hear from the card again... */ + ifp->if_timer = 5; scp->tx_queued++; m_freem(mbp); @@ -443,15 +490,17 @@ switch (command) { - case SIOCSIFFLAGS: + case SIOCSIFFLAGS: +#if XE_DEBUG > 1 + device_printf(scp->dev, "ioctl: SIOCSIFFLAGS: 0x%04x\n", ifp->if_flags); +#endif /* * If the interface is marked up and stopped, then start it. If it is * marked down and running, then stop it. */ if (ifp->if_flags & IFF_UP) { if (!(ifp->if_flags & IFF_RUNNING)) { - xe_hard_reset(scp); - xe_setmedia(scp); + xe_reset(scp); xe_init(scp); } } @@ -459,27 +508,36 @@ if (ifp->if_flags & IFF_RUNNING) xe_stop(scp); } - /* XXX: intentional fall-through ? */ - case SIOCADDMULTI: - case SIOCDELMULTI: + /* FALL THROUGH (handle changes to PROMISC/ALLMULTI flags) */ + + case SIOCADDMULTI: + case SIOCDELMULTI: +#if XE_DEBUG > 1 + device_printf(scp->dev, "ioctl: SIOC{ADD,DEL}MULTI\n"); +#endif /* - * Multicast list has (maybe) changed; set the hardware filter - * accordingly. This also serves to deal with promiscuous mode if we have - * a BPF listener active. + * Multicast list has (maybe) changed; set the hardware filters + * accordingly. */ - xe_setmulti(scp); + xe_set_multicast(scp); error = 0; break; - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + case SIOCGIFMEDIA: +#if XE_DEBUG > 1 + device_printf(scp->dev, "ioctl: bounce to ifmedia_ioctl\n"); +#endif /* * Someone wants to get/set media options. */ error = ifmedia_ioctl(ifp, (struct ifreq *)data, &scp->ifmedia, command); break; - default: + default: +#if XE_DEBUG > 1 + device_printf(scp->dev, "ioctl: bounce to ether_ioctl\n"); +#endif error = ether_ioctl(ifp, command, data); } @@ -512,245 +570,272 @@ { struct xe_softc *scp = (struct xe_softc *) xscp; struct ifnet *ifp; - u_int16_t rx_bytes, rxs, txs; - u_int8_t psr, isr, esr, rsr; + u_int8_t psr, isr, esr, rsr, rst0, txst0, txst1, coll; ifp = &scp->arpcom.ac_if; - rx_bytes = 0; /* Bytes received on this interrupt */ + + /* Disable interrupts */ + if (scp->mohawk) + XE_OUTB(XE_CR, 0); - if (scp->mohawk) { - XE_OUTB(XE_CR, 0); /* Disable interrupts */ - } + /* Cache current register page */ + psr = XE_INB(XE_PR); - psr = XE_INB(XE_PR); /* Stash the current register page */ + /* Read ISR to see what caused this interrupt */ + while ((isr = XE_INB(XE_ISR)) != 0) { - /* - * Read ISR to see what caused this interrupt. Note that this clears the - * ISR on CE2 type cards. - */ - if ((isr = XE_INB(XE_ISR)) && isr != 0xff) { + /* 0xff might mean the card is no longer around */ + if (isr == 0xff) { +#if XE_DEBUG > 2 + device_printf(scp->dev, "intr: interrupt received for missing card?\n"); +#endif + break; + } - esr = XE_INB(XE_ESR); /* Read the other status registers */ + /* Read other status registers */ XE_SELECT_PAGE(0x40); - rxs = XE_INB(XE_RST0); - XE_OUTB(XE_RST0, ~rxs & 0xff); - txs = XE_INB(XE_TXST0); - txs |= XE_INB(XE_TXST1) << 8; + rst0 = XE_INB(XE_RST0); + XE_OUTB(XE_RST0, 0); + txst0 = XE_INB(XE_TXST0); + txst1 = XE_INB(XE_TXST1); + coll = txst1 & XE_TXST1_RETRY_COUNT; XE_OUTB(XE_TXST0, 0); XE_OUTB(XE_TXST1, 0); XE_SELECT_PAGE(0); #if XE_DEBUG > 2 - printf("xe%d: ISR=%#2.2x ESR=%#2.2x RST=%#2.2x TXST=%#4.4x\n", unit, isr, esr, rxs, txs); + device_printf(scp->dev, "intr: ISR=0x%02x, RST=0x%02x, TXT=0x%02x%02x, COLL=0x%01x\n", isr, rst0, txst1, txst0, coll); #endif - /* - * Handle transmit interrupts - */ + /* Handle transmitted packet(s) */ if (isr & XE_ISR_TX_PACKET) { - u_int8_t new_tpr, sent; - - if ((new_tpr = XE_INB(XE_TPR)) < scp->tx_tpr) /* Update packet count */ - sent = (0xff - scp->tx_tpr) + new_tpr; /* TPR rolled over */ - else - sent = new_tpr - scp->tx_tpr; + u_int8_t tpr, sent; + + /* Update packet count, accounting for rollover */ + tpr = XE_INB(XE_TPR); + sent = -scp->tx_tpr + tpr; - if (sent > 0) { /* Packets sent since last interrupt */ - scp->tx_tpr = new_tpr; + /* Update statistics if we actually sent anything */ + if (sent > 0) { + scp->tx_tpr = tpr; scp->tx_queued -= sent; ifp->if_opackets += sent; - ifp->if_collisions += scp->tx_collisions; + ifp->if_collisions += coll; /* - * Collision stats are a PITA. If multiples frames have been sent, we - * distribute any outstanding collision count equally amongst them. - * However, if we're missing interrupts we're quite likely to also - * miss some collisions; thus the total count will be off anyway. - * Likewise, if we miss a frame dropped due to excessive collisions - * any outstanding collisions count will be held against the next - * frame to be successfully sent. Hopefully it averages out in the - * end! - * XXX - This will screw up if tx_collisions/sent > 14. FIX IT! + * According to the Xircom manual, Dingo will sometimes manage to + * transmit a packet with triggering an interrupt. If this happens, + * we have sent > 1 and the collision count only reflects collisions + * on the last packet sent (the one that triggered the interrupt). + * Collision stats might therefore be a bit low, but there doesn't + * seem to be anything we can do about that. */ - switch (scp->tx_collisions) { - case 0: + + switch (coll) { + case 0: break; - case 1: + case 1: scp->mibdata.dot3StatsSingleCollisionFrames++; scp->mibdata.dot3StatsCollFrequencies[0]++; break; - default: - if (sent == 1) { - scp->mibdata.dot3StatsMultipleCollisionFrames++; - scp->mibdata.dot3StatsCollFrequencies[scp->tx_collisions-1]++; - } - else { /* Distribute across multiple frames */ - scp->mibdata.dot3StatsMultipleCollisionFrames += sent; - scp->mibdata. - dot3StatsCollFrequencies[scp->tx_collisions/sent] += sent - scp->tx_collisions%sent; - scp->mibdata. - dot3StatsCollFrequencies[scp->tx_collisions/sent + 1] += scp->tx_collisions%sent; - } + default: + scp->mibdata.dot3StatsMultipleCollisionFrames++; + scp->mibdata.dot3StatsCollFrequencies[coll-1]++; } - scp->tx_collisions = 0; } ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; } - if (txs & 0x0002) { /* Excessive collisions (packet dropped) */ - ifp->if_collisions += 16; - ifp->if_oerrors++; - scp->tx_collisions = 0; - scp->mibdata.dot3StatsExcessiveCollisions++; - scp->mibdata.dot3StatsMultipleCollisionFrames++; - scp->mibdata.dot3StatsCollFrequencies[15]++; - XE_OUTB(XE_CR, XE_CR_RESTART_TX); + + /* Handle most MAC interrupts */ + if (isr & XE_ISR_MAC_INTR) { + +#if 0 + /* Carrier sense lost -- only in 10Mbit HDX mode */ + if (txst0 & XE_TXST0_NO_CARRIER || !(txst1 & XE_TXST1_LINK_STATUS)) { >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310151658.h9FGwZAj087116>